cxl/mem: Support Secure Erase
authorDavidlohr Bueso <dave@stgolabs.net>
Mon, 12 Jun 2023 18:10:37 +0000 (11:10 -0700)
committerDan Williams <dan.j.williams@intel.com>
Sun, 25 Jun 2023 22:34:41 +0000 (15:34 -0700)
Implement support for the non-pmem exclusive secure erase, per
CXL specs. Create a write-only 'security/erase' sysfs file to
perform the requested operation.

As with the sanitation this requires the device being offline
and thus no active HPA-DPA decoding.

The expectation is that userspace can use it such as:

cxl disable-memdev memX
echo 1 > /sys/bus/cxl/devices/memX/security/erase
cxl enable-memdev memX

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Fan Ni <fan.ni@samsung.com>
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Link: https://lore.kernel.org/r/20230612181038.14421-7-dave@stgolabs.net
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Documentation/ABI/testing/sysfs-bus-cxl
drivers/cxl/core/mbox.c
drivers/cxl/core/memdev.c
drivers/cxl/cxlmem.h

index f86fe36713758f149049fc420199625941b3d1d7..c619493e413ec1483bae94ba1eb21a43cac6f43c 100644 (file)
@@ -85,6 +85,16 @@ Description:
                the device to be not be actively decoding any HPA ranges.
 
 
+What            /sys/bus/cxl/devices/memX/security/erase
+Date:           June, 2023
+KernelVersion:  v6.5
+Contact:        linux-cxl@vger.kernel.org
+Description:
+               (WO) Write a boolean 'true' string value to this attribute to
+               secure erase user data by changing the media encryption keys for
+               all user data areas of the device.
+
+
 What:          /sys/bus/cxl/devices/*/devtype
 Date:          June, 2021
 KernelVersion: v5.14
index e6e60c8b606e6016fbc9f1df7bb2ec4a89d42a40..c86d0b3159b0a71f47908f1a24bdbe3b0d7d33a0 100644 (file)
@@ -1102,7 +1102,7 @@ int cxl_mem_sanitize(struct cxl_dev_state *cxlds, u16 cmd)
        };
        struct cxl_mbox_cmd mbox_cmd = { .opcode = cmd };
 
-       if (cmd != CXL_MBOX_OP_SANITIZE)
+       if (cmd != CXL_MBOX_OP_SANITIZE && cmd != CXL_MBOX_OP_SECURE_ERASE)
                return -EINVAL;
 
        rc = cxl_internal_send_cmd(cxlds, &sec_cmd);
@@ -1120,6 +1120,10 @@ int cxl_mem_sanitize(struct cxl_dev_state *cxlds, u16 cmd)
        if (sec_out & CXL_PMEM_SEC_STATE_USER_PASS_SET)
                return -EINVAL;
 
+       if (cmd == CXL_MBOX_OP_SECURE_ERASE &&
+           sec_out & CXL_PMEM_SEC_STATE_LOCKED)
+               return -EINVAL;
+
        rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
        if (rc < 0) {
                dev_err(cxlds->dev, "Failed to sanitize device : %d", rc);
index bdd1edfd62e81803d5d30f9ad348913effc15db2..ed8de7efddef87508bca032b5fd8abb315ffb4e8 100644 (file)
@@ -163,6 +163,33 @@ static ssize_t security_sanitize_store(struct device *dev,
 static struct device_attribute dev_attr_security_sanitize =
        __ATTR(sanitize, 0200, NULL, security_sanitize_store);
 
+static ssize_t security_erase_store(struct device *dev,
+                                   struct device_attribute *attr,
+                                   const char *buf, size_t len)
+{
+       struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
+       struct cxl_dev_state *cxlds = cxlmd->cxlds;
+       struct cxl_port *port = dev_get_drvdata(&cxlmd->dev);
+       ssize_t rc;
+       bool erase;
+
+       if (kstrtobool(buf, &erase) || !erase)
+               return -EINVAL;
+
+       if (!port || !is_cxl_endpoint(port))
+               return -EINVAL;
+
+       /* ensure no regions are mapped to this memdev */
+       if (port->commit_end != -1)
+               return -EBUSY;
+
+       rc = cxl_mem_sanitize(cxlds, CXL_MBOX_OP_SECURE_ERASE);
+
+       return rc ? rc : len;
+}
+static struct device_attribute dev_attr_security_erase =
+       __ATTR(erase, 0200, NULL, security_erase_store);
+
 static int cxl_get_poison_by_memdev(struct cxl_memdev *cxlmd)
 {
        struct cxl_dev_state *cxlds = cxlmd->cxlds;
@@ -411,6 +438,7 @@ static struct attribute *cxl_memdev_ram_attributes[] = {
 static struct attribute *cxl_memdev_security_attributes[] = {
        &dev_attr_security_state.attr,
        &dev_attr_security_sanitize.attr,
+       &dev_attr_security_erase.attr,
        NULL,
 };
 
index 5b84f27fc76a2c9c69acf228b8f622c49c6f5fdf..78ff518012bff033715679a868264208583a3027 100644 (file)
@@ -388,6 +388,7 @@ enum cxl_opcode {
        CXL_MBOX_OP_SCAN_MEDIA          = 0x4304,
        CXL_MBOX_OP_GET_SCAN_MEDIA      = 0x4305,
        CXL_MBOX_OP_SANITIZE            = 0x4400,
+       CXL_MBOX_OP_SECURE_ERASE        = 0x4401,
        CXL_MBOX_OP_GET_SECURITY_STATE  = 0x4500,
        CXL_MBOX_OP_SET_PASSPHRASE      = 0x4501,
        CXL_MBOX_OP_DISABLE_PASSPHRASE  = 0x4502,