Merge branch 'for-6.2/cxl-security' into for-6.2/cxl
authorDan Williams <dan.j.williams@intel.com>
Mon, 5 Dec 2022 20:30:38 +0000 (12:30 -0800)
committerDan Williams <dan.j.williams@intel.com>
Mon, 5 Dec 2022 20:30:38 +0000 (12:30 -0800)
Pick CXL PMEM security commands for v6.2. Resolve conflicts with the
removal of the cxl_pmem_wq.

1  2 
drivers/cxl/core/pmem.c
drivers/cxl/core/region.c
drivers/cxl/cxl.h
drivers/cxl/cxlmem.h
drivers/cxl/pmem.c
tools/testing/cxl/Kbuild
tools/testing/cxl/test/mem.c

Simple merge
Simple merge
index 9a212ab3cae4b5b294c0b9ff23c93d511e830f83,e5e1abceeca7cf47006463b139d2e8df7e2a79d7..8b7fb33d368bb462a43b1f52bec730a8c8cd762e
@@@ -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 {
        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 {
Simple merge
index 0910367a3eadee7545f953bf5ad630c6ec99fc5b,ab40c93c44e5093a1e71e3a082dbc851cf3a7e2e..2fc8070b6a17dd113ab4eaf2b1d12bb0a006e213
  #include "cxlmem.h"
  #include "cxl.h"
  
 -/*
 - * 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;
 -
+ extern const struct nvdimm_security_ops *cxl_security_ops;
  static __read_mostly DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX);
  
  static void clear_exclusive(void *cxlds)
  
  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);
        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 = {
Simple merge
index b59c5976b2d901ec77d5d8194ec12573947f0d4e,35d9ad04e0d650a6e01b205f64b82c6ceddb7e1a..5e4ecd93f1d2d5b4dfd4d54dae4da37af2f7fe7e
@@@ -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);