Bypass cpu_cache_invalidate_memregion() and checks when doing testing
using CONFIG_NVDIMM_SECURITY_TEST flag. The bypass allows testing on
QEMU where cpu_cache_has_invalidate_memregion() fails. Usage of
cpu_cache_invalidate_memregion() is not needed for nfit_test security
testing.

Signed-off-by: Dave Jiang <dave.ji...@intel.com>
---
 drivers/acpi/nfit/intel.c |   51 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c
index fa0e57e35162..38069f10c316 100644
--- a/drivers/acpi/nfit/intel.c
+++ b/drivers/acpi/nfit/intel.c
@@ -191,6 +191,39 @@ static int intel_security_change_key(struct nvdimm *nvdimm,
        }
 }
 
+static bool intel_has_invalidate_memregion(struct nvdimm *nvdimm)
+{
+       struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
+       struct acpi_nfit_desc *acpi_desc = nfit_mem->acpi_desc;
+       struct device *dev = acpi_desc->dev;
+
+       if (!cpu_cache_has_invalidate_memregion()) {
+               if (IS_ENABLED(CONFIG_NVDIMM_SECURITY_TEST)) {
+                       dev_warn_once(dev,
+                                     "Bypassing 
cpu_cache_has_invalidate_memregion() check for testing!\n");
+                       return true;
+               }
+               return false;
+       }
+
+       return true;
+}
+
+static void intel_invalidate_memregion(struct nvdimm *nvdimm)
+{
+       struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
+       struct acpi_nfit_desc *acpi_desc = nfit_mem->acpi_desc;
+       struct device *dev = acpi_desc->dev;
+
+       if (IS_ENABLED(CONFIG_NVDIMM_SECURITY_TEST)) {
+               dev_warn_once(dev,
+                             "Bypassing cpu_cache_invalidate_memergion() for 
testing!\n");
+               return;
+       }
+
+       cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY);
+}
+
 static int __maybe_unused intel_security_unlock(struct nvdimm *nvdimm,
                const struct nvdimm_key_data *key_data)
 {
@@ -212,7 +245,7 @@ static int __maybe_unused intel_security_unlock(struct 
nvdimm *nvdimm,
        if (!test_bit(NVDIMM_INTEL_UNLOCK_UNIT, &nfit_mem->dsm_mask))
                return -ENOTTY;
 
-       if (!cpu_cache_has_invalidate_memregion())
+       if (!intel_has_invalidate_memregion(nvdimm))
                return -EINVAL;
 
        memcpy(nd_cmd.cmd.passphrase, key_data->data,
@@ -230,7 +263,7 @@ static int __maybe_unused intel_security_unlock(struct 
nvdimm *nvdimm,
        }
 
        /* DIMM unlocked, invalidate all CPU caches before we read it */
-       cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY);
+       intel_invalidate_memregion(nvdimm);
 
        return 0;
 }
@@ -299,11 +332,11 @@ static int __maybe_unused intel_security_erase(struct 
nvdimm *nvdimm,
        if (!test_bit(cmd, &nfit_mem->dsm_mask))
                return -ENOTTY;
 
-       if (!cpu_cache_has_invalidate_memregion())
+       if (!intel_has_invalidate_memregion(nvdimm))
                return -EINVAL;
 
        /* flush all cache before we erase DIMM */
-       cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY);
+       intel_invalidate_memregion(nvdimm);
        memcpy(nd_cmd.cmd.passphrase, key->data,
                        sizeof(nd_cmd.cmd.passphrase));
        rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
@@ -323,7 +356,7 @@ static int __maybe_unused intel_security_erase(struct 
nvdimm *nvdimm,
        }
 
        /* DIMM erased, invalidate all CPU caches before we read it */
-       cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY);
+       intel_invalidate_memregion(nvdimm);
        return 0;
 }
 
@@ -346,7 +379,7 @@ static int __maybe_unused 
intel_security_query_overwrite(struct nvdimm *nvdimm)
        if (!test_bit(NVDIMM_INTEL_QUERY_OVERWRITE, &nfit_mem->dsm_mask))
                return -ENOTTY;
 
-       if (!cpu_cache_has_invalidate_memregion())
+       if (!intel_has_invalidate_memregion(nvdimm))
                return -EINVAL;
 
        rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
@@ -363,7 +396,7 @@ static int __maybe_unused 
intel_security_query_overwrite(struct nvdimm *nvdimm)
        }
 
        /* flush all cache before we make the nvdimms available */
-       cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY);
+       intel_invalidate_memregion(nvdimm);
        return 0;
 }
 
@@ -388,11 +421,11 @@ static int __maybe_unused intel_security_overwrite(struct 
nvdimm *nvdimm,
        if (!test_bit(NVDIMM_INTEL_OVERWRITE, &nfit_mem->dsm_mask))
                return -ENOTTY;
 
-       if (!cpu_cache_has_invalidate_memregion())
+       if (!intel_has_invalidate_memregion(nvdimm))
                return -EINVAL;
 
        /* flush all cache before we erase DIMM */
-       cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY);
+       intel_invalidate_memregion(nvdimm);
        memcpy(nd_cmd.cmd.passphrase, nkey->data,
                        sizeof(nd_cmd.cmd.passphrase));
        rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);



Reply via email to