Add "--injectable-errors"/"-N" option to show injectable error information for CXL objects. Applicable CXL objects are CXL memory devices, where the information reported is whether poison is injectable, and CXL busses, which list the CXL protocol error types available for injection.
The CXL protocol error types will be the same across busses because the information comes from the ACPI EINJ error types table (ACPI v6.5 18.6), but are presented under the bus for easier filtering. Signed-off-by: Ben Cheatham <benjamin.cheat...@amd.com> --- 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 56eb516..6d65947 100644 --- a/Documentation/cxl/cxl-list.txt +++ b/Documentation/cxl/cxl-list.txt @@ -469,6 +469,38 @@ OPTIONS } ---- +-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 @@ -485,7 +517,8 @@ OPTIONS 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 956a46e..34f8387 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; }; @@ -91,6 +92,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 e65bd80..6f1a7cf 100644 --- a/cxl/json.c +++ b/cxl/json.c @@ -855,6 +855,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) @@ -930,6 +936,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(); @@ -945,6 +953,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 5f77d87..d43b47e 100644 --- a/cxl/list.c +++ b/cxl/list.c @@ -60,6 +60,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"), OPT_STRING(0, "debugfs", &debugfs, "debugfs mount point", "mount point of kernel debugfs (defaults to '/sys/kernel/debug')"), @@ -127,6 +129,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, -- 2.34.1