[PATCH v3 19/54] dyndbg: detect class_id reservation conflicts

Louis Chauvet louis.chauvet at bootlin.com
Tue Apr 15 10:03:14 UTC 2025



Le 02/04/2025 à 19:41, Jim Cromie a écrit :
> If a module _DEFINEs + _USEs 2 or more classmaps, it must devise them
> to share the per-module 0..62 class-id space; ie their respective
> base,+length reservations cannot overlap.
> 
> To detect conflicts at modprobe, add ddebug_class_range_overlap(),
> call it from ddebug_add_module(), and WARN and return -EINVAL when
> they're detected.
> 
> test_dynamic_debug.c:
> 
> If built with -DFORCE_CLASSID_CONFLICT, the test-modules get 2 bad
> DYNDBG_CLASS_DEFINE declarations, into parent and the _submod.  These
> conflict with one of the good ones in the parent (D2_CORE..etc),
> causing the modprobe(s) to warn
> 
> Signed-off-by: Jim Cromie <jim.cromie at gmail.com>

Reviewed-by: Louis Chauvet <louis.chauvet at bootlin.com>

> ---
> ---
>   lib/dynamic_debug.c      | 29 +++++++++++++++++++++++++++++
>   lib/test_dynamic_debug.c |  8 ++++++++
>   2 files changed, 37 insertions(+)
> 
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index 53e261dbf81e..56b503af0b31 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -1267,6 +1267,22 @@ static void ddebug_apply_class_users(const struct _ddebug_info *di)
>   	(_dst)->info._vec.len = nc;					\
>   })
>   
> +static int __maybe_unused
> +ddebug_class_range_overlap(struct _ddebug_class_map *cm,
> +			   u64 *reserved_ids)
> +{
> +	u64 range = (((1ULL << cm->length) - 1) << cm->base);
> +
> +	if (range & *reserved_ids) {
> +		pr_err("[%d..%d] on %s conflicts with %llx\n", cm->base,
> +		       cm->base + cm->length - 1, cm->class_names[0],
> +		       *reserved_ids);
> +		return -EINVAL;
> +	}
> +	*reserved_ids |= range;
> +	return 0;
> +}
> +
>   /*
>    * Allocate a new ddebug_table for the given module
>    * and add it to the global list.
> @@ -1276,6 +1292,7 @@ static int ddebug_add_module(struct _ddebug_info *di)
>   	struct ddebug_table *dt;
>   	struct _ddebug_class_map *cm;
>   	struct _ddebug_class_user *cli;
> +	u64 reserved_ids = 0;
>   	int i;
>   
>   	if (!di->descs.len)
> @@ -1301,6 +1318,13 @@ static int ddebug_add_module(struct _ddebug_info *di)
>   	dd_mark_vector_subrange(i, dt, cm, di, maps);
>   	dd_mark_vector_subrange(i, dt, cli, di, users);
>   
> +	for_subvec(i, cm, &dt->info, maps)
> +		if (ddebug_class_range_overlap(cm, &reserved_ids))
> +			goto cleanup;
> +	for_subvec(i, cli, &dt->info, users)
> +		if (ddebug_class_range_overlap(cli->map, &reserved_ids))
> +			goto cleanup;
> +
>   	if (dt->info.maps.len)
>   		ddebug_apply_class_maps(&dt->info);
>   
> @@ -1313,6 +1337,11 @@ static int ddebug_add_module(struct _ddebug_info *di)
>   
>   	vpr_info("%3u debug prints in module %s\n", di->descs.len, di->mod_name);
>   	return 0;
> +cleanup:
> +	WARN_ONCE("dyndbg multi-classmap conflict in %s\n", di->mod_name);
> +	kfree(dt);
> +	return -EINVAL;
> +
>   }
>   
>   /* helper for ddebug_dyndbg_(boot|module)_param_cb */
> diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
> index 1070107f74f1..e42916b08fd4 100644
> --- a/lib/test_dynamic_debug.c
> +++ b/lib/test_dynamic_debug.c
> @@ -128,6 +128,14 @@ DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
>   DYNAMIC_DEBUG_CLASSMAP_PARAM(disjoint_bits, p);
>   DYNAMIC_DEBUG_CLASSMAP_PARAM(level_num, p);
>   
> +#ifdef FORCE_CLASSID_CONFLICT
> +/*
> + * Enable with -Dflag on compile to test overlapping class-id range
> + * detection.  This should warn on modprobes.
> + */
> +DYNDBG_CLASSMAP_DEFINE(classid_range_conflict, 0, D2_CORE + 1, "D3_CORE");
> +#endif
> +
>   #else /* TEST_DYNAMIC_DEBUG_SUBMOD */
>   
>   /*

-- 
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com




More information about the intel-gvt-dev mailing list