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 cxl_test security testing.
Signed-off-by: Dave Jiang <dave.ji...@intel.com> --- drivers/cxl/security.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c index cbd005ceb091..2b5088af8fc4 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -111,6 +111,31 @@ static int cxl_pmem_security_freeze(struct nvdimm *nvdimm) return cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_FREEZE_SECURITY, NULL, 0, NULL, 0); } +static bool cxl_has_invalidate_memregion(struct cxl_nvdimm *cxl_nvd) +{ + if (!cpu_cache_has_invalidate_memregion()) { + if (IS_ENABLED(CONFIG_NVDIMM_SECURITY_TEST)) { + dev_warn_once(&cxl_nvd->dev, + "Bypassing cpu_cache_has_invalidate_memregion() check for testing!\n"); + return true; + } + return false; + } + + return true; +} + +static void cxl_invalidate_memregion(struct cxl_nvdimm *cxl_nvd) +{ + if (IS_ENABLED(CONFIG_NVDIMM_SECURITY_TEST)) { + dev_warn_once(&cxl_nvd->dev, + "Bypassing cpu_cache_invalidate_memergion() for testing!\n"); + return; + } + + cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY); +} + static int cxl_pmem_security_unlock(struct nvdimm *nvdimm, const struct nvdimm_key_data *key_data) { @@ -120,7 +145,7 @@ static int cxl_pmem_security_unlock(struct nvdimm *nvdimm, u8 pass[NVDIMM_PASSPHRASE_LEN]; int rc; - if (!cpu_cache_has_invalidate_memregion()) + if (!cxl_has_invalidate_memregion(cxl_nvd)) return -EINVAL; memcpy(pass, key_data->data, NVDIMM_PASSPHRASE_LEN); @@ -130,7 +155,7 @@ static int cxl_pmem_security_unlock(struct nvdimm *nvdimm, return rc; /* DIMM unlocked, invalidate all CPU caches before we read it */ - cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY); + cxl_invalidate_memregion(cxl_nvd); return 0; } @@ -144,21 +169,21 @@ static int cxl_pmem_security_passphrase_erase(struct nvdimm *nvdimm, struct cxl_pass_erase erase; int rc; - if (!cpu_cache_has_invalidate_memregion()) + if (!cxl_has_invalidate_memregion(cxl_nvd)) return -EINVAL; erase.type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER : CXL_PMEM_SEC_PASS_USER; memcpy(erase.pass, key->data, NVDIMM_PASSPHRASE_LEN); /* Flush all cache before we erase mem device */ - cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY); + cxl_invalidate_memregion(cxl_nvd); rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE, &erase, sizeof(erase), NULL, 0); if (rc < 0) return rc; /* mem device erased, invalidate all CPU caches before data is read */ - cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY); + cxl_invalidate_memregion(cxl_nvd); return 0; }