nfit_test overrode the security_show() sysfs attribute function in nvdimm
dimm_devs in order to allow testing of security unlock. With the
introduction of CXL security commands, the trick to override
security_show() becomes significantly more complicated. By introdcing a
security flag CONFIG_NVDIMM_SECURITY_TEST, libnvdimm can just toggle the
check via a compile option. In addition the original override can can be
removed from tools/testing/nvdimm/.
The flag will also be used to bypass cpu_cache_invalidate_memregion() when
set in a different commit. This allows testing on QEMU with nfit_test or
cxl_test since cpu_cache_has_invalidate_memregion() checks whether
X86_FEATURE_HYPERVISOR cpu feature flag is set on x86.
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/166983618758.2734609.18031639517065867138.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
          core devm_memremap_pages() implementation and other
          infrastructure.
 
+config NVDIMM_SECURITY_TEST
+       bool "Enable NVDIMM security unit tests"
+       depends on NVDIMM_KEYS
+       help
+         The NVDIMM and CXL subsystems support unit testing of their device
+         security state machines. The NVDIMM_SECURITY_TEST option disables CPU
+         cache maintenance operations around events like secure erase and
+         overwrite.  Also, when enabled, the NVDIMM subsystem core helps the unit
+         test implement a mock state machine.
+
+         Select N if unsure.
+
 endif
 
 }
 static DEVICE_ATTR_RO(available_slots);
 
-__weak ssize_t security_show(struct device *dev,
+ssize_t security_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
        struct nvdimm *nvdimm = to_nvdimm(dev);
 
+       /*
+        * For the test version we need to poll the "hardware" in order
+        * to get the updated status for unlock testing.
+        */
+       if (IS_ENABLED(CONFIG_NVDIMM_SECURITY_TEST))
+               nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
+
        if (test_bit(NVDIMM_SECURITY_OVERWRITE, &nvdimm->sec.flags))
                return sprintf(buf, "overwrite\n");
        if (test_bit(NVDIMM_SECURITY_DISABLED, &nvdimm->sec.flags))
 
                        || !nvdimm->sec.flags)
                return -EIO;
 
+       /* cxl_test needs this to pre-populate the security state */
+       if (IS_ENABLED(CONFIG_NVDIMM_SECURITY_TEST))
+               nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
+
        /* No need to go further if security is disabled */
        if (test_bit(NVDIMM_SECURITY_DISABLED, &nvdimm->sec.flags))
                return 0;
 
 libnvdimm-$(CONFIG_NVDIMM_PFN) += $(NVDIMM_SRC)/pfn_devs.o
 libnvdimm-$(CONFIG_NVDIMM_DAX) += $(NVDIMM_SRC)/dax_devs.o
 libnvdimm-$(CONFIG_NVDIMM_KEYS) += $(NVDIMM_SRC)/security.o
-libnvdimm-y += dimm_devs.o
 libnvdimm-y += libnvdimm_test.o
 libnvdimm-y += config_check.o
 
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright Intel Corp. 2018 */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/nd.h>
-#include "pmem.h"
-#include "pfn.h"
-#include "nd.h"
-#include "nd-core.h"
-
-ssize_t security_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct nvdimm *nvdimm = to_nvdimm(dev);
-
-       /*
-        * For the test version we need to poll the "hardware" in order
-        * to get the updated status for unlock testing.
-        */
-       nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
-
-       if (test_bit(NVDIMM_SECURITY_DISABLED, &nvdimm->sec.flags))
-               return sprintf(buf, "disabled\n");
-       if (test_bit(NVDIMM_SECURITY_UNLOCKED, &nvdimm->sec.flags))
-               return sprintf(buf, "unlocked\n");
-       if (test_bit(NVDIMM_SECURITY_LOCKED, &nvdimm->sec.flags))
-               return sprintf(buf, "locked\n");
-       return -ENOTTY;
-}