cxl/mem: Add debugfs attributes for poison inject and clear
authorAlison Schofield <alison.schofield@intel.com>
Wed, 19 Apr 2023 03:26:29 +0000 (20:26 -0700)
committerDan Williams <dan.j.williams@intel.com>
Sun, 23 Apr 2023 19:08:39 +0000 (12:08 -0700)
Inject and Clear Poison commands are optionally supported by CXL
memdev devices and are intended for use in debug environments only.
Add debugfs attributes for user access.

Documentation/ABI/testing/debugfs-cxl describes the usage.

Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/0c9ea8e671b8e58465d18722788b60d325c675c7.1681874357.git.alison.schofield@intel.com
Tested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Documentation/ABI/testing/debugfs-cxl [new file with mode: 0644]
drivers/cxl/mem.c

diff --git a/Documentation/ABI/testing/debugfs-cxl b/Documentation/ABI/testing/debugfs-cxl
new file mode 100644 (file)
index 0000000..fe61d37
--- /dev/null
@@ -0,0 +1,35 @@
+What:          /sys/kernel/debug/cxl/memX/inject_poison
+Date:          April, 2023
+KernelVersion: v6.4
+Contact:       linux-cxl@vger.kernel.org
+Description:
+               (WO) When a Device Physical Address (DPA) is written to this
+               attribute, the memdev driver sends an inject poison command to
+               the device for the specified address. The DPA must be 64-byte
+               aligned and the length of the injected poison is 64-bytes. If
+               successful, the device returns poison when the address is
+               accessed through the CXL.mem bus. Injecting poison adds the
+               address to the device's Poison List and the error source is set
+               to Injected. In addition, the device adds a poison creation
+               event to its internal Informational Event log, updates the
+               Event Status register, and if configured, interrupts the host.
+               It is not an error to inject poison into an address that
+               already has poison present and no error is returned. The
+               inject_poison attribute is only visible for devices supporting
+               the capability.
+
+
+What:          /sys/kernel/debug/memX/clear_poison
+Date:          April, 2023
+KernelVersion: v6.4
+Contact:       linux-cxl@vger.kernel.org
+Description:
+               (WO) When a Device Physical Address (DPA) is written to this
+               attribute, the memdev driver sends a clear poison command to
+               the device for the specified address. Clearing poison removes
+               the address from the device's Poison List and writes 0 (zero)
+               for 64 bytes starting at address. It is not an error to clear
+               poison from an address that does not have poison set. If the
+               device cannot clear poison from the address, -ENXIO is returned.
+               The clear_poison attribute is only visible for devices
+               supporting the capability.
index b6a413f..10caf18 100644 (file)
@@ -94,6 +94,26 @@ static int devm_cxl_add_endpoint(struct device *host, struct cxl_memdev *cxlmd,
        return 0;
 }
 
+static int cxl_debugfs_poison_inject(void *data, u64 dpa)
+{
+       struct cxl_memdev *cxlmd = data;
+
+       return cxl_inject_poison(cxlmd, dpa);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(cxl_poison_inject_fops, NULL,
+                        cxl_debugfs_poison_inject, "%llx\n");
+
+static int cxl_debugfs_poison_clear(void *data, u64 dpa)
+{
+       struct cxl_memdev *cxlmd = data;
+
+       return cxl_clear_poison(cxlmd, dpa);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(cxl_poison_clear_fops, NULL,
+                        cxl_debugfs_poison_clear, "%llx\n");
+
 static int cxl_mem_probe(struct device *dev)
 {
        struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
@@ -117,6 +137,14 @@ static int cxl_mem_probe(struct device *dev)
 
        dentry = cxl_debugfs_create_dir(dev_name(dev));
        debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
+
+       if (test_bit(CXL_POISON_ENABLED_INJECT, cxlds->poison.enabled_cmds))
+               debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
+                                   &cxl_poison_inject_fops);
+       if (test_bit(CXL_POISON_ENABLED_CLEAR, cxlds->poison.enabled_cmds))
+               debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
+                                   &cxl_poison_clear_fops);
+
        rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
        if (rc)
                return rc;