Commit 180ffd33 authored by Davidlohr Bueso's avatar Davidlohr Bueso Committed by Dan Williams
Browse files

cxl/mem: Support Secure Erase



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: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: default avatarDave Jiang <dave.jiang@intel.com>
Reviewed-by: default avatarFan Ni <fan.ni@samsung.com>
Signed-off-by: default avatarDavidlohr Bueso <dave@stgolabs.net>
Link: https://lore.kernel.org/r/20230612181038.14421-7-dave@stgolabs.net


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent c5c39217
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
+5 −1
Original line number Diff line number Diff line
@@ -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);
+28 −0
Original line number Diff line number Diff line
@@ -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,
};

+1 −0
Original line number Diff line number Diff line
@@ -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,