From: Dan Williams Date: Mon, 5 Dec 2022 20:30:38 +0000 (-0800) Subject: Merge branch 'for-6.2/cxl-security' into for-6.2/cxl X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=95dddcb5e86381abddeb1ccab5b5826fdcc74c70;p=linux.git Merge branch 'for-6.2/cxl-security' into for-6.2/cxl Pick CXL PMEM security commands for v6.2. Resolve conflicts with the removal of the cxl_pmem_wq. --- 95dddcb5e86381abddeb1ccab5b5826fdcc74c70 diff --cc drivers/cxl/cxl.h index 9a212ab3cae4b,e5e1abceeca7c..8b7fb33d368bb --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@@ -394,8 -392,7 +400,9 @@@ struct cxl_region_params * @id: This region's id. Id is globally unique across all regions * @mode: Endpoint decoder allocation / access mode * @type: Endpoint decoder target type + * @cxl_nvb: nvdimm bridge for coordinating @cxlr_pmem setup / shutdown + * @cxlr_pmem: (for pmem regions) cached copy of the nvdimm bridge + * @flags: Region state flags * @params: active + config params for the region */ struct cxl_region { @@@ -403,8 -400,7 +410,9 @@@ int id; enum cxl_decoder_mode mode; enum cxl_decoder_type type; + struct cxl_nvdimm_bridge *cxl_nvb; + struct cxl_pmem_region *cxlr_pmem; + unsigned long flags; struct cxl_region_params params; }; @@@ -414,11 -424,18 +422,14 @@@ struct cxl_nvdimm_bridge struct cxl_port *port; struct nvdimm_bus *nvdimm_bus; struct nvdimm_bus_descriptor nd_desc; - struct work_struct state_work; - enum cxl_nvdimm_brige_state state; }; + #define CXL_DEV_ID_LEN 19 + struct cxl_nvdimm { struct device dev; struct cxl_memdev *cxlmd; - struct cxl_nvdimm_bridge *bridge; - struct xarray pmem_regions; + u8 dev_id[CXL_DEV_ID_LEN]; /* for nvdimm, string of 'serial' */ }; struct cxl_pmem_region_mapping { diff --cc drivers/cxl/pmem.c index 0910367a3eade,ab40c93c44e50..2fc8070b6a17d --- a/drivers/cxl/pmem.c +++ b/drivers/cxl/pmem.c @@@ -11,6 -11,15 +11,8 @@@ #include "cxlmem.h" #include "cxl.h" + extern const struct nvdimm_security_ops *cxl_security_ops; + -/* - * Ordered workqueue for cxl nvdimm device arrival and departure - * to coordinate bus rescans when a bridge arrives and trigger remove - * operations when the bridge is removed. - */ -static struct workqueue_struct *cxl_pmem_wq; - static __read_mostly DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX); static void clear_exclusive(void *cxlds) @@@ -20,9 -29,63 +22,44 @@@ static void unregister_nvdimm(void *nvdimm) { - struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); - struct cxl_nvdimm_bridge *cxl_nvb = cxl_nvd->bridge; - struct cxl_pmem_region *cxlr_pmem; - unsigned long index; - - device_lock(&cxl_nvb->dev); - dev_set_drvdata(&cxl_nvd->dev, NULL); - xa_for_each(&cxl_nvd->pmem_regions, index, cxlr_pmem) { - get_device(&cxlr_pmem->dev); - device_unlock(&cxl_nvb->dev); - - device_release_driver(&cxlr_pmem->dev); - put_device(&cxlr_pmem->dev); - - device_lock(&cxl_nvb->dev); - } - device_unlock(&cxl_nvb->dev); - nvdimm_delete(nvdimm); - cxl_nvd->bridge = NULL; } + static ssize_t provider_show(struct device *dev, struct device_attribute *attr, char *buf) + { + struct nvdimm *nvdimm = to_nvdimm(dev); + struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); + + return sysfs_emit(buf, "%s\n", dev_name(&cxl_nvd->dev)); + } + static DEVICE_ATTR_RO(provider); + + static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf) + { + struct nvdimm *nvdimm = to_nvdimm(dev); + struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); + struct cxl_dev_state *cxlds = cxl_nvd->cxlmd->cxlds; + + return sysfs_emit(buf, "%lld\n", cxlds->serial); + } + static DEVICE_ATTR_RO(id); + + static struct attribute *cxl_dimm_attributes[] = { + &dev_attr_id.attr, + &dev_attr_provider.attr, + NULL + }; + + static const struct attribute_group cxl_dimm_attribute_group = { + .name = "cxl", + .attrs = cxl_dimm_attributes, + }; + + static const struct attribute_group *cxl_dimm_attribute_groups[] = { + &cxl_dimm_attribute_group, + NULL + }; + static int cxl_nvdimm_probe(struct device *dev) { struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); @@@ -42,13 -115,23 +79,15 @@@ set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask); set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask); set_bit(ND_CMD_SET_CONFIG_DATA, &cmd_mask); - nvdimm = nvdimm_create(cxl_nvb->nvdimm_bus, cxl_nvd, NULL, flags, - cmd_mask, 0, NULL); + nvdimm = __nvdimm_create(cxl_nvb->nvdimm_bus, cxl_nvd, + cxl_dimm_attribute_groups, flags, + cmd_mask, 0, NULL, cxl_nvd->dev_id, + cxl_security_ops, NULL); - if (!nvdimm) { - rc = -ENOMEM; - goto out; - } + if (!nvdimm) + return -ENOMEM; dev_set_drvdata(dev, nvdimm); - cxl_nvd->bridge = cxl_nvb; - rc = devm_add_action_or_reset(dev, unregister_nvdimm, nvdimm); -out: - device_unlock(&cxl_nvb->dev); - put_device(&cxl_nvb->dev); - - return rc; + return devm_add_action_or_reset(dev, unregister_nvdimm, nvdimm); } static struct cxl_driver cxl_nvdimm_driver = { diff --cc tools/testing/cxl/test/mem.c index b59c5976b2d90,35d9ad04e0d65..5e4ecd93f1d2d --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@@ -320,9 -647,50 +679,48 @@@ static int cxl_mock_mem_probe(struct pl return 0; } + static ssize_t security_lock_show(struct device *dev, + struct device_attribute *attr, char *buf) + { + struct cxl_mockmem_data *mdata = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%u\n", + !!(mdata->security_state & CXL_PMEM_SEC_STATE_LOCKED)); + } + + static ssize_t security_lock_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) + { + struct cxl_mockmem_data *mdata = dev_get_drvdata(dev); + u32 mask = CXL_PMEM_SEC_STATE_FROZEN | CXL_PMEM_SEC_STATE_USER_PLIMIT | + CXL_PMEM_SEC_STATE_MASTER_PLIMIT; + int val; + + if (kstrtoint(buf, 0, &val) < 0) + return -EINVAL; + + if (val == 1) { + if (!(mdata->security_state & CXL_PMEM_SEC_STATE_USER_PASS_SET)) + return -ENXIO; + mdata->security_state |= CXL_PMEM_SEC_STATE_LOCKED; + mdata->security_state &= ~mask; + } else { + return -EINVAL; + } + return count; + } + + static DEVICE_ATTR_RW(security_lock); + + static struct attribute *cxl_mock_mem_attrs[] = { + &dev_attr_security_lock.attr, + NULL + }; + ATTRIBUTE_GROUPS(cxl_mock_mem); + static const struct platform_device_id cxl_mock_mem_ids[] = { - { .name = "cxl_mem", }, + { .name = "cxl_mem", 0 }, + { .name = "cxl_rcd", 1 }, { }, }; MODULE_DEVICE_TABLE(platform, cxl_mock_mem_ids);