@@ -1407,6 +1407,32 @@ CXL_EXPORT int cxl_memdev_enable(struct cxl_memdev *memdev)
return 0;
}
+CXL_EXPORT int cxl_memdev_inject_poison(struct cxl_memdev *memdev,
+ const char *address)
+{
+ struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
+ char *path = memdev->dev_buf;
+ int len = memdev->buf_len, rc;
+
+ if (snprintf(path, len, "%s/inject_poison",
+ memdev->dev_path) >= len) {
+ err(ctx, "%s: buffer too small\n",
+ cxl_memdev_get_devname(memdev));
+ return -ENXIO;
+ }
+ rc = sysfs_write_attr(ctx, path, address);
+ if (rc < 0) {
+ fprintf(stderr, "%s: Failed write sysfs attr inject_poison\n",
+ cxl_memdev_get_devname(memdev));
+ return rc;
+ }
+
+ dbg(ctx, "%s: poison injected at %s\n", cxl_memdev_get_devname(memdev),
+ address);
+
+ return 0;
+}
+
static struct cxl_endpoint *cxl_port_find_endpoint(struct cxl_port *parent_port,
struct cxl_memdev *memdev)
{
@@ -242,3 +242,8 @@ global:
cxl_target_get_firmware_node;
cxl_dport_get_firmware_node;
} LIBCXL_3;
+
+LIBCXL_5 {
+global:
+ cxl_memdev_inject_poison;
+} LIBCXL_4;
@@ -68,6 +68,7 @@ int cxl_memdev_read_label(struct cxl_memdev *memdev, void *buf, size_t length,
size_t offset);
int cxl_memdev_write_label(struct cxl_memdev *memdev, void *buf, size_t length,
size_t offset);
+int cxl_memdev_inject_poison(struct cxl_memdev *memdev, const char *address);
#define cxl_memdev_foreach(ctx, memdev) \
for (memdev = cxl_memdev_get_first(ctx); \