acpi/nfit, libnvdimm: Introduce nvdimm_security_ops
Some NVDIMMs, like the ones defined by the NVDIMM_FAMILY_INTEL command set, expose a security capability to lock the DIMMs at poweroff and require a passphrase to unlock them. The security model is derived from ATA security. In anticipation of other DIMMs implementing a similar scheme, and to abstract the core security implementation away from the device-specific details, introduce nvdimm_security_ops. Initially only a status retrieval operation, ->state(), is defined, along with the base infrastructure and definitions for future operations. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Co-developed-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
@@ -370,23 +370,60 @@ static ssize_t available_slots_show(struct device *dev,
|
||||
}
|
||||
static DEVICE_ATTR_RO(available_slots);
|
||||
|
||||
static ssize_t security_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct nvdimm *nvdimm = to_nvdimm(dev);
|
||||
|
||||
switch (nvdimm->sec.state) {
|
||||
case NVDIMM_SECURITY_DISABLED:
|
||||
return sprintf(buf, "disabled\n");
|
||||
case NVDIMM_SECURITY_UNLOCKED:
|
||||
return sprintf(buf, "unlocked\n");
|
||||
case NVDIMM_SECURITY_LOCKED:
|
||||
return sprintf(buf, "locked\n");
|
||||
case NVDIMM_SECURITY_FROZEN:
|
||||
return sprintf(buf, "frozen\n");
|
||||
case NVDIMM_SECURITY_OVERWRITE:
|
||||
return sprintf(buf, "overwrite\n");
|
||||
}
|
||||
|
||||
return -ENOTTY;
|
||||
}
|
||||
static DEVICE_ATTR_RO(security);
|
||||
|
||||
static struct attribute *nvdimm_attributes[] = {
|
||||
&dev_attr_state.attr,
|
||||
&dev_attr_flags.attr,
|
||||
&dev_attr_commands.attr,
|
||||
&dev_attr_available_slots.attr,
|
||||
&dev_attr_security.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static umode_t nvdimm_visible(struct kobject *kobj, struct attribute *a, int n)
|
||||
{
|
||||
struct device *dev = container_of(kobj, typeof(*dev), kobj);
|
||||
struct nvdimm *nvdimm = to_nvdimm(dev);
|
||||
|
||||
if (a != &dev_attr_security.attr)
|
||||
return a->mode;
|
||||
if (nvdimm->sec.state < 0)
|
||||
return 0;
|
||||
return a->mode;
|
||||
}
|
||||
|
||||
struct attribute_group nvdimm_attribute_group = {
|
||||
.attrs = nvdimm_attributes,
|
||||
.is_visible = nvdimm_visible,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nvdimm_attribute_group);
|
||||
|
||||
struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,
|
||||
void *provider_data, const struct attribute_group **groups,
|
||||
unsigned long flags, unsigned long cmd_mask, int num_flush,
|
||||
struct resource *flush_wpq, const char *dimm_id)
|
||||
struct resource *flush_wpq, const char *dimm_id,
|
||||
const struct nvdimm_security_ops *sec_ops)
|
||||
{
|
||||
struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL);
|
||||
struct device *dev;
|
||||
@@ -413,6 +450,12 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,
|
||||
dev->type = &nvdimm_device_type;
|
||||
dev->devt = MKDEV(nvdimm_major, nvdimm->id);
|
||||
dev->groups = groups;
|
||||
nvdimm->sec.ops = sec_ops;
|
||||
/*
|
||||
* Security state must be initialized before device_add() for
|
||||
* attribute visibility.
|
||||
*/
|
||||
nvdimm->sec.state = nvdimm_security_state(nvdimm);
|
||||
nd_device_register(dev);
|
||||
|
||||
return nvdimm;
|
||||
|
Reference in New Issue
Block a user