Commit | Line | Data |
---|---|---|
32828115 DJ |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* Copyright(c) 2022 Intel Corporation. All rights reserved. */ | |
3 | #include <linux/libnvdimm.h> | |
4 | #include <asm/unaligned.h> | |
5 | #include <linux/module.h> | |
6 | #include <linux/async.h> | |
7 | #include <linux/slab.h> | |
8 | #include "cxlmem.h" | |
9 | #include "cxl.h" | |
10 | ||
11 | static unsigned long cxl_pmem_get_security_flags(struct nvdimm *nvdimm, | |
12 | enum nvdimm_passphrase_type ptype) | |
13 | { | |
14 | struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); | |
15 | struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; | |
16 | struct cxl_dev_state *cxlds = cxlmd->cxlds; | |
17 | unsigned long security_flags = 0; | |
18 | u32 sec_out; | |
19 | int rc; | |
20 | ||
21 | rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_SECURITY_STATE, NULL, 0, | |
22 | &sec_out, sizeof(sec_out)); | |
23 | if (rc < 0) | |
24 | return 0; | |
25 | ||
26 | if (ptype == NVDIMM_MASTER) { | |
27 | if (sec_out & CXL_PMEM_SEC_STATE_MASTER_PASS_SET) | |
28 | set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags); | |
29 | else | |
30 | set_bit(NVDIMM_SECURITY_DISABLED, &security_flags); | |
31 | if (sec_out & CXL_PMEM_SEC_STATE_MASTER_PLIMIT) | |
32 | set_bit(NVDIMM_SECURITY_FROZEN, &security_flags); | |
33 | return security_flags; | |
34 | } | |
35 | ||
36 | if (sec_out & CXL_PMEM_SEC_STATE_USER_PASS_SET) { | |
37 | if (sec_out & CXL_PMEM_SEC_STATE_FROZEN || | |
38 | sec_out & CXL_PMEM_SEC_STATE_USER_PLIMIT) | |
39 | set_bit(NVDIMM_SECURITY_FROZEN, &security_flags); | |
40 | ||
41 | if (sec_out & CXL_PMEM_SEC_STATE_LOCKED) | |
42 | set_bit(NVDIMM_SECURITY_LOCKED, &security_flags); | |
43 | else | |
44 | set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags); | |
45 | } else { | |
46 | set_bit(NVDIMM_SECURITY_DISABLED, &security_flags); | |
47 | } | |
48 | ||
49 | return security_flags; | |
50 | } | |
51 | ||
99746940 DJ |
52 | static int cxl_pmem_security_change_key(struct nvdimm *nvdimm, |
53 | const struct nvdimm_key_data *old_data, | |
54 | const struct nvdimm_key_data *new_data, | |
55 | enum nvdimm_passphrase_type ptype) | |
56 | { | |
57 | struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); | |
58 | struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; | |
59 | struct cxl_dev_state *cxlds = cxlmd->cxlds; | |
60 | struct cxl_set_pass set_pass; | |
61 | int rc; | |
62 | ||
63 | set_pass.type = ptype == NVDIMM_MASTER ? | |
64 | CXL_PMEM_SEC_PASS_MASTER : CXL_PMEM_SEC_PASS_USER; | |
65 | memcpy(set_pass.old_pass, old_data->data, NVDIMM_PASSPHRASE_LEN); | |
66 | memcpy(set_pass.new_pass, new_data->data, NVDIMM_PASSPHRASE_LEN); | |
67 | ||
68 | rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_SET_PASSPHRASE, | |
69 | &set_pass, sizeof(set_pass), NULL, 0); | |
70 | return rc; | |
71 | } | |
72 | ||
32828115 DJ |
73 | static const struct nvdimm_security_ops __cxl_security_ops = { |
74 | .get_flags = cxl_pmem_get_security_flags, | |
99746940 | 75 | .change_key = cxl_pmem_security_change_key, |
32828115 DJ |
76 | }; |
77 | ||
78 | const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; |