Adding a flag for nvdimm->flags to support erase functions. While it's ok
to hold the nvdimm_bus lock for secure erase due to minimal time to execute
the command, overwrite requires a significantly longer time and makes this
impossible. The flag will block any drivers from being loaded and DIMMs
being probed.

Signed-off-by: Dave Jiang <[email protected]>
---
 drivers/nvdimm/dimm_devs.c   |    5 +++++
 drivers/nvdimm/region_devs.c |    5 +++++
 drivers/nvdimm/security.c    |   15 +++++++++++++++
 include/linux/libnvdimm.h    |    2 ++
 4 files changed, 27 insertions(+)

diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index bc432b7c17b8..e9f11d35ff2b 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -569,6 +569,11 @@ int nvdimm_security_freeze(struct nvdimm *nvdimm)
        if (nvdimm->sec.state < 0)
                return -EIO;
 
+       if (test_bit(NDD_SECURITY_BUSY, &nvdimm->flags)) {
+               dev_warn(&nvdimm->dev, "Security operation in progress.\n");
+               return -EBUSY;
+       }
+
        rc = nvdimm->sec.ops->freeze(nvdimm);
        nvdimm->sec.state = nvdimm_security_state(nvdimm);
 
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index 174a418cb171..4e69b1d03c05 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -79,6 +79,11 @@ int nd_region_activate(struct nd_region *nd_region)
                struct nd_mapping *nd_mapping = &nd_region->mapping[i];
                struct nvdimm *nvdimm = nd_mapping->nvdimm;
 
+               if (test_bit(NDD_SECURITY_BUSY, &nvdimm->flags)) {
+                       nvdimm_bus_unlock(&nd_region->dev);
+                       return -EBUSY;
+               }
+
                /* at least one null hint slot per-dimm for the "no-hint" case 
*/
                flush_data_size += sizeof(void *);
                num_flush = min_not_zero(num_flush, nvdimm->num_flush);
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 4836f2fda271..1edd298e6e27 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -143,6 +143,11 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
                        || nvdimm->sec.state < 0)
                return -EIO;
 
+       if (test_bit(NDD_SECURITY_BUSY, &nvdimm->flags)) {
+               dev_warn(dev, "Security operation in progress.\n");
+               return -EBUSY;
+       }
+
        /*
         * If the pre-OS has unlocked the DIMM, attempt to send the key
         * from request_key() to the hardware for verification.  Failure
@@ -203,6 +208,11 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, 
unsigned int keyid)
                return -EIO;
        }
 
+       if (test_bit(NDD_SECURITY_BUSY, &nvdimm->flags)) {
+               dev_warn(dev, "Security operation in progress.\n");
+               return -EBUSY;
+       }
+
        key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
        if (!key)
                return -ENOKEY;
@@ -288,6 +298,11 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned 
int keyid)
                return -EIO;
        }
 
+       if (test_bit(NDD_SECURITY_BUSY, &nvdimm->flags)) {
+               dev_warn(dev, "Security operation in progress.\n");
+               return -EBUSY;
+       }
+
        key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
        if (!key)
                return -ENOKEY;
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index 9a6cb7067dc7..8507d2896ae0 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -38,6 +38,8 @@ enum {
        NDD_UNARMED = 1,
        /* locked memory devices should not be accessed */
        NDD_LOCKED = 2,
+       /* memory under security wipes should not be accessed */
+       NDD_SECURITY_BUSY = 3,
 
        /* need to set a limit somewhere, but yes, this is likely overkill */
        ND_IOCTL_MAX_BUFLEN = SZ_4M,

_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to