On 12/9/25 10:14 AM, Ben Cheatham wrote:
> Add the "--injectable-errors"/"-N" option to show injectable error
> information for CXL devices. The applicable devices are CXL memory
> devices and CXL busses.
>
> For CXL memory devices the option reports whether the device supports
> poison injection (the "--media-errors"/"-L" option shows injected
> poison).
>
> For CXL busses the option shows injectable CXL protocol error types. The
> information will be the same across busses because the error types are
> system-wide. The information is presented under the bus for easier
> filtering.
>
> Update the man page for 'cxl-list' to show the usage of the new option.
>
> Signed-off-by: Ben Cheatham <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
> ---
> Documentation/cxl/cxl-list.txt | 35 +++++++++++++++++++++++++++++++++-
> cxl/filter.h | 3 +++
> cxl/json.c | 30 +++++++++++++++++++++++++++++
> cxl/list.c | 3 +++
> util/json.h | 1 +
> 5 files changed, 71 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/cxl/cxl-list.txt b/Documentation/cxl/cxl-list.txt
> index 0595638..35ff542 100644
> --- a/Documentation/cxl/cxl-list.txt
> +++ b/Documentation/cxl/cxl-list.txt
> @@ -471,6 +471,38 @@ The media-errors option is only available with
> '-Dlibtracefs=enabled'.
> }
> ----
>
> +-N::
> +--injectable-errors::
> + Include injectable error information in the output. For CXL memory
> devices
> + this includes whether poison is injectable through the kernel debug
> filesystem.
> + The types of CXL protocol errors available for injection into
> downstream ports
> + are listed as part of a CXL bus object.
> +
> +----
> +# cxl list -NB
> +[
> + {
> + "bus":"root0",
> + "provider":"ACPI.CXL",
> + "injectable_protocol_errors":[
> + "mem-correctable",
> + "mem-fatal",
> + ]
> + }
> +]
> +
> +# cxl list -N
> +[
> + {
> + "memdev":"mem0",
> + "pmem_size":268435456,
> + "ram_size":268435456,
> + "serial":2,
> + "poison_injectable":true
> + }
> +]
> +
> +----
> -v::
> --verbose::
> Increase verbosity of the output. This can be specified
> @@ -487,7 +519,8 @@ The media-errors option is only available with
> '-Dlibtracefs=enabled'.
> devices with --idle.
> - *-vvv*
> Everything *-vv* provides, plus enable
> - --health, --partition, and --media-errors.
> + --health, --partition, --media-errors, and
> + --injectable-errors.
>
> --debug::
> If the cxl tool was built with debug enabled, turn on debug
> diff --git a/cxl/filter.h b/cxl/filter.h
> index 70463c4..6c5fe68 100644
> --- a/cxl/filter.h
> +++ b/cxl/filter.h
> @@ -31,6 +31,7 @@ struct cxl_filter_params {
> bool alert_config;
> bool dax;
> bool media_errors;
> + bool inj_errors;
> int verbose;
> struct log_ctx ctx;
> };
> @@ -93,6 +94,8 @@ static inline unsigned long cxl_filter_to_flags(struct
> cxl_filter_params *param)
> flags |= UTIL_JSON_DAX | UTIL_JSON_DAX_DEVS;
> if (param->media_errors)
> flags |= UTIL_JSON_MEDIA_ERRORS;
> + if (param->inj_errors)
> + flags |= UTIL_JSON_INJ_ERRORS;
> return flags;
> }
>
> diff --git a/cxl/json.c b/cxl/json.c
> index bde4589..2917477 100644
> --- a/cxl/json.c
> +++ b/cxl/json.c
> @@ -675,6 +675,12 @@ struct json_object *util_cxl_memdev_to_json(struct
> cxl_memdev *memdev,
> json_object_object_add(jdev, "firmware", jobj);
> }
>
> + if (flags & UTIL_JSON_INJ_ERRORS) {
> + jobj =
> json_object_new_boolean(cxl_memdev_has_poison_injection(memdev));
> + if (jobj)
> + json_object_object_add(jdev, "poison_injectable", jobj);
> + }
> +
> if (flags & UTIL_JSON_MEDIA_ERRORS) {
> jobj = util_cxl_poison_list_to_json(NULL, memdev, flags);
> if (jobj)
> @@ -750,6 +756,8 @@ struct json_object *util_cxl_bus_to_json(struct cxl_bus
> *bus,
> unsigned long flags)
> {
> const char *devname = cxl_bus_get_devname(bus);
> + struct cxl_ctx *ctx = cxl_bus_get_ctx(bus);
> + struct cxl_protocol_error *perror;
> struct json_object *jbus, *jobj;
>
> jbus = json_object_new_object();
> @@ -765,6 +773,28 @@ struct json_object *util_cxl_bus_to_json(struct cxl_bus
> *bus,
> json_object_object_add(jbus, "provider", jobj);
>
> json_object_set_userdata(jbus, bus, NULL);
> +
> + if (flags & UTIL_JSON_INJ_ERRORS) {
> + jobj = json_object_new_array();
> + if (!jobj)
> + return jbus;
> +
> + cxl_protocol_error_foreach(ctx, perror)
> + {
> + struct json_object *jerr_str;
> + const char *perror_str;
> +
> + perror_str = cxl_protocol_error_get_str(perror);
> +
> + jerr_str = json_object_new_string(perror_str);
> + if (jerr_str)
> + json_object_array_add(jobj, jerr_str);
> + }
> +
> + json_object_object_add(jbus, "injectable_protocol_errors",
> + jobj);
> + }
> +
> return jbus;
> }
>
> diff --git a/cxl/list.c b/cxl/list.c
> index 0b25d78..a505ed6 100644
> --- a/cxl/list.c
> +++ b/cxl/list.c
> @@ -59,6 +59,8 @@ static const struct option options[] = {
> "include alert configuration information"),
> OPT_BOOLEAN('L', "media-errors", ¶m.media_errors,
> "include media-error information "),
> + OPT_BOOLEAN('N', "injectable-errors", ¶m.inj_errors,
> + "include injectable error information"),
> OPT_INCR('v', "verbose", ¶m.verbose, "increase output detail"),
> #ifdef ENABLE_DEBUG
> OPT_BOOLEAN(0, "debug", &debug, "debug list walk"),
> @@ -124,6 +126,7 @@ int cmd_list(int argc, const char **argv, struct cxl_ctx
> *ctx)
> param.alert_config = true;
> param.dax = true;
> param.media_errors = true;
> + param.inj_errors = true;
> /* fallthrough */
> case 2:
> param.idle = true;
> diff --git a/util/json.h b/util/json.h
> index 560f845..57278cb 100644
> --- a/util/json.h
> +++ b/util/json.h
> @@ -21,6 +21,7 @@ enum util_json_flags {
> UTIL_JSON_TARGETS = (1 << 11),
> UTIL_JSON_PARTITION = (1 << 12),
> UTIL_JSON_ALERT_CONFIG = (1 << 13),
> + UTIL_JSON_INJ_ERRORS = (1 << 14),
> };
>
> void util_display_json_array(FILE *f_out, struct json_object *jarray,