]> git.itanic.dy.fi Git - linux-stable/commitdiff
tools/testing/cxl: Add 'sanitize notifier' support
authorDan Williams <dan.j.williams@intel.com>
Wed, 4 Oct 2023 23:50:09 +0000 (16:50 -0700)
committerDan Williams <dan.j.williams@intel.com>
Mon, 9 Oct 2023 18:35:45 +0000 (11:35 -0700)
Allow for cxl_test regression of the sanitize notifier. Reuse the core
setup infrastructure, and trigger notifications upon any sanitize
submission with a programmable notification delay.

Cc: Davidlohr Bueso <dave@stgolabs.net>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
tools/testing/cxl/test/mem.c

index ab311b59899acef905df93a7647ed67de1f6a7a2..76bdb1ac5816f863f9ee5b70a51acd2fec8a2067 100644 (file)
@@ -89,6 +89,12 @@ static struct cxl_cel_entry mock_cel[] = {
                .effect = cpu_to_le16(EFFECT(CONF_CHANGE_COLD_RESET) |
                                      EFFECT(CONF_CHANGE_IMMEDIATE)),
        },
+       {
+               .opcode = cpu_to_le16(CXL_MBOX_OP_SANITIZE),
+               .effect = cpu_to_le16(EFFECT(DATA_CHANGE_IMMEDIATE) |
+                                     EFFECT(SECURITY_CHANGE_IMMEDIATE) |
+                                     EFFECT(BACKGROUND_OP)),
+       },
 };
 
 /* See CXL 2.0 Table 181 Get Health Info Output Payload */
@@ -152,6 +158,7 @@ struct cxl_mockmem_data {
        struct cxl_memdev_state *mds;
        u8 event_buf[SZ_4K];
        u64 timestamp;
+       unsigned long sanitize_timeout;
 };
 
 static struct mock_event_log *event_find_log(struct device *dev, int log_type)
@@ -567,9 +574,26 @@ static int mock_partition_info(struct cxl_mbox_cmd *cmd)
        return 0;
 }
 
+void cxl_mockmem_sanitize_work(struct work_struct *work)
+{
+       struct cxl_memdev_state *mds =
+               container_of(work, typeof(*mds), security.poll_dwork.work);
+
+       mutex_lock(&mds->mbox_mutex);
+       if (mds->security.sanitize_node)
+               sysfs_notify_dirent(mds->security.sanitize_node);
+       mds->security.sanitize_active = false;
+       mutex_unlock(&mds->mbox_mutex);
+
+       dev_dbg(mds->cxlds.dev, "sanitize complete\n");
+}
+
 static int mock_sanitize(struct cxl_mockmem_data *mdata,
                         struct cxl_mbox_cmd *cmd)
 {
+       struct cxl_memdev_state *mds = mdata->mds;
+       int rc = 0;
+
        if (cmd->size_in != 0)
                return -EINVAL;
 
@@ -585,7 +609,16 @@ static int mock_sanitize(struct cxl_mockmem_data *mdata,
                return -ENXIO;
        }
 
-       return 0; /* assume less than 2 secs, no bg */
+       mutex_lock(&mds->mbox_mutex);
+       if (schedule_delayed_work(&mds->security.poll_dwork,
+                                 msecs_to_jiffies(mdata->sanitize_timeout))) {
+               mds->security.sanitize_active = true;
+               dev_dbg(mds->cxlds.dev, "sanitize issued\n");
+       } else
+               rc = -EBUSY;
+       mutex_unlock(&mds->mbox_mutex);
+
+       return rc;
 }
 
 static int mock_secure_erase(struct cxl_mockmem_data *mdata,
@@ -1419,6 +1452,7 @@ static int cxl_mock_mem_probe(struct platform_device *pdev)
        mds->mbox_send = cxl_mock_mbox_send;
        mds->payload_size = SZ_4K;
        mds->event.buf = (struct cxl_get_event_payload *) mdata->event_buf;
+       INIT_DELAYED_WORK(&mds->security.poll_dwork, cxl_mockmem_sanitize_work);
 
        cxlds = &mds->cxlds;
        cxlds->serial = pdev->id;
@@ -1458,6 +1492,10 @@ static int cxl_mock_mem_probe(struct platform_device *pdev)
        if (rc)
                return rc;
 
+       rc = devm_cxl_sanitize_setup_notifier(&pdev->dev, cxlmd);
+       if (rc)
+               return rc;
+
        cxl_mem_get_event_records(mds, CXLDEV_EVENT_STATUS_ALL);
 
        return 0;
@@ -1526,10 +1564,38 @@ static ssize_t fw_buf_checksum_show(struct device *dev,
 
 static DEVICE_ATTR_RO(fw_buf_checksum);
 
+static ssize_t sanitize_timeout_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
+{
+       struct cxl_mockmem_data *mdata = dev_get_drvdata(dev);
+
+       return sysfs_emit(buf, "%lu\n", mdata->sanitize_timeout);
+}
+
+static ssize_t sanitize_timeout_store(struct device *dev,
+                                     struct device_attribute *attr,
+                                     const char *buf, size_t count)
+{
+       struct cxl_mockmem_data *mdata = dev_get_drvdata(dev);
+       unsigned long val;
+       int rc;
+
+       rc = kstrtoul(buf, 0, &val);
+       if (rc)
+               return rc;
+
+       mdata->sanitize_timeout = val;
+
+       return count;
+}
+
+static DEVICE_ATTR_RW(sanitize_timeout);
+
 static struct attribute *cxl_mock_mem_attrs[] = {
        &dev_attr_security_lock.attr,
        &dev_attr_event_trigger.attr,
        &dev_attr_fw_buf_checksum.attr,
+       &dev_attr_sanitize_timeout.attr,
        NULL
 };
 ATTRIBUTE_GROUPS(cxl_mock_mem);