aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/nvdimm/dimm_devs.c2
-rw-r--r--tools/testing/nvdimm/Kbuild1
-rw-r--r--tools/testing/nvdimm/dimm_devs.c41
-rw-r--r--tools/testing/nvdimm/test/nfit.c180
4 files changed, 223 insertions, 1 deletions
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index bd3f156463b1..4890310df874 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -370,7 +370,7 @@ static ssize_t available_slots_show(struct device *dev,
370} 370}
371static DEVICE_ATTR_RO(available_slots); 371static DEVICE_ATTR_RO(available_slots);
372 372
373static ssize_t security_show(struct device *dev, 373__weak ssize_t security_show(struct device *dev,
374 struct device_attribute *attr, char *buf) 374 struct device_attribute *attr, char *buf)
375{ 375{
376 struct nvdimm *nvdimm = to_nvdimm(dev); 376 struct nvdimm *nvdimm = to_nvdimm(dev);
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index 33ea40777205..10ddf223055b 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -81,6 +81,7 @@ libnvdimm-$(CONFIG_BTT) += $(NVDIMM_SRC)/btt_devs.o
81libnvdimm-$(CONFIG_NVDIMM_PFN) += $(NVDIMM_SRC)/pfn_devs.o 81libnvdimm-$(CONFIG_NVDIMM_PFN) += $(NVDIMM_SRC)/pfn_devs.o
82libnvdimm-$(CONFIG_NVDIMM_DAX) += $(NVDIMM_SRC)/dax_devs.o 82libnvdimm-$(CONFIG_NVDIMM_DAX) += $(NVDIMM_SRC)/dax_devs.o
83libnvdimm-$(CONFIG_NVDIMM_KEYS) += $(NVDIMM_SRC)/security.o 83libnvdimm-$(CONFIG_NVDIMM_KEYS) += $(NVDIMM_SRC)/security.o
84libnvdimm-y += dimm_devs.o
84libnvdimm-y += libnvdimm_test.o 85libnvdimm-y += libnvdimm_test.o
85libnvdimm-y += config_check.o 86libnvdimm-y += config_check.o
86 87
diff --git a/tools/testing/nvdimm/dimm_devs.c b/tools/testing/nvdimm/dimm_devs.c
new file mode 100644
index 000000000000..e75238404555
--- /dev/null
+++ b/tools/testing/nvdimm/dimm_devs.c
@@ -0,0 +1,41 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright Intel Corp. 2018 */
3#include <linux/init.h>
4#include <linux/module.h>
5#include <linux/moduleparam.h>
6#include <linux/nd.h>
7#include "pmem.h"
8#include "pfn.h"
9#include "nd.h"
10#include "nd-core.h"
11
12ssize_t security_show(struct device *dev,
13 struct device_attribute *attr, char *buf)
14{
15 struct nvdimm *nvdimm = to_nvdimm(dev);
16
17 /*
18 * For the test version we need to poll the "hardware" in order
19 * to get the updated status for unlock testing.
20 */
21 nvdimm->sec.state = nvdimm_security_state(nvdimm, false);
22 nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, true);
23
24 switch (nvdimm->sec.state) {
25 case NVDIMM_SECURITY_DISABLED:
26 return sprintf(buf, "disabled\n");
27 case NVDIMM_SECURITY_UNLOCKED:
28 return sprintf(buf, "unlocked\n");
29 case NVDIMM_SECURITY_LOCKED:
30 return sprintf(buf, "locked\n");
31 case NVDIMM_SECURITY_FROZEN:
32 return sprintf(buf, "frozen\n");
33 case NVDIMM_SECURITY_OVERWRITE:
34 return sprintf(buf, "overwrite\n");
35 default:
36 return -ENOTTY;
37 }
38
39 return -ENOTTY;
40}
41
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 01ec04bf91b5..30f89fd740d9 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -142,6 +142,10 @@ static u32 handle[] = {
142 142
143static unsigned long dimm_fail_cmd_flags[ARRAY_SIZE(handle)]; 143static unsigned long dimm_fail_cmd_flags[ARRAY_SIZE(handle)];
144static int dimm_fail_cmd_code[ARRAY_SIZE(handle)]; 144static int dimm_fail_cmd_code[ARRAY_SIZE(handle)];
145struct nfit_test_sec {
146 u8 state;
147 u8 passphrase[32];
148} dimm_sec_info[NUM_DCR];
145 149
146static const struct nd_intel_smart smart_def = { 150static const struct nd_intel_smart smart_def = {
147 .flags = ND_INTEL_SMART_HEALTH_VALID 151 .flags = ND_INTEL_SMART_HEALTH_VALID
@@ -933,6 +937,138 @@ static int override_return_code(int dimm, unsigned int func, int rc)
933 return rc; 937 return rc;
934} 938}
935 939
940static int nd_intel_test_cmd_security_status(struct nfit_test *t,
941 struct nd_intel_get_security_state *nd_cmd,
942 unsigned int buf_len, int dimm)
943{
944 struct device *dev = &t->pdev.dev;
945 struct nfit_test_sec *sec = &dimm_sec_info[dimm];
946
947 nd_cmd->status = 0;
948 nd_cmd->state = sec->state;
949 dev_dbg(dev, "security state (%#x) returned\n", nd_cmd->state);
950
951 return 0;
952}
953
954static int nd_intel_test_cmd_unlock_unit(struct nfit_test *t,
955 struct nd_intel_unlock_unit *nd_cmd,
956 unsigned int buf_len, int dimm)
957{
958 struct device *dev = &t->pdev.dev;
959 struct nfit_test_sec *sec = &dimm_sec_info[dimm];
960
961 if (!(sec->state & ND_INTEL_SEC_STATE_LOCKED) ||
962 (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
963 nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
964 dev_dbg(dev, "unlock unit: invalid state: %#x\n",
965 sec->state);
966 } else if (memcmp(nd_cmd->passphrase, sec->passphrase,
967 ND_INTEL_PASSPHRASE_SIZE) != 0) {
968 nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS;
969 dev_dbg(dev, "unlock unit: invalid passphrase\n");
970 } else {
971 nd_cmd->status = 0;
972 sec->state = ND_INTEL_SEC_STATE_ENABLED;
973 dev_dbg(dev, "Unit unlocked\n");
974 }
975
976 dev_dbg(dev, "unlocking status returned: %#x\n", nd_cmd->status);
977 return 0;
978}
979
980static int nd_intel_test_cmd_set_pass(struct nfit_test *t,
981 struct nd_intel_set_passphrase *nd_cmd,
982 unsigned int buf_len, int dimm)
983{
984 struct device *dev = &t->pdev.dev;
985 struct nfit_test_sec *sec = &dimm_sec_info[dimm];
986
987 if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
988 nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
989 dev_dbg(dev, "set passphrase: wrong security state\n");
990 } else if (memcmp(nd_cmd->old_pass, sec->passphrase,
991 ND_INTEL_PASSPHRASE_SIZE) != 0) {
992 nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS;
993 dev_dbg(dev, "set passphrase: wrong passphrase\n");
994 } else {
995 memcpy(sec->passphrase, nd_cmd->new_pass,
996 ND_INTEL_PASSPHRASE_SIZE);
997 sec->state |= ND_INTEL_SEC_STATE_ENABLED;
998 nd_cmd->status = 0;
999 dev_dbg(dev, "passphrase updated\n");
1000 }
1001
1002 return 0;
1003}
1004
1005static int nd_intel_test_cmd_freeze_lock(struct nfit_test *t,
1006 struct nd_intel_freeze_lock *nd_cmd,
1007 unsigned int buf_len, int dimm)
1008{
1009 struct device *dev = &t->pdev.dev;
1010 struct nfit_test_sec *sec = &dimm_sec_info[dimm];
1011
1012 if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED)) {
1013 nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
1014 dev_dbg(dev, "freeze lock: wrong security state\n");
1015 } else {
1016 sec->state |= ND_INTEL_SEC_STATE_FROZEN;
1017 nd_cmd->status = 0;
1018 dev_dbg(dev, "security frozen\n");
1019 }
1020
1021 return 0;
1022}
1023
1024static int nd_intel_test_cmd_disable_pass(struct nfit_test *t,
1025 struct nd_intel_disable_passphrase *nd_cmd,
1026 unsigned int buf_len, int dimm)
1027{
1028 struct device *dev = &t->pdev.dev;
1029 struct nfit_test_sec *sec = &dimm_sec_info[dimm];
1030
1031 if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
1032 (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
1033 nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
1034 dev_dbg(dev, "disable passphrase: wrong security state\n");
1035 } else if (memcmp(nd_cmd->passphrase, sec->passphrase,
1036 ND_INTEL_PASSPHRASE_SIZE) != 0) {
1037 nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS;
1038 dev_dbg(dev, "disable passphrase: wrong passphrase\n");
1039 } else {
1040 memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
1041 sec->state = 0;
1042 dev_dbg(dev, "disable passphrase: done\n");
1043 }
1044
1045 return 0;
1046}
1047
1048static int nd_intel_test_cmd_secure_erase(struct nfit_test *t,
1049 struct nd_intel_secure_erase *nd_cmd,
1050 unsigned int buf_len, int dimm)
1051{
1052 struct device *dev = &t->pdev.dev;
1053 struct nfit_test_sec *sec = &dimm_sec_info[dimm];
1054
1055 if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
1056