diff options
-rw-r--r-- | drivers/cxl/core/mbox.c | 1 | ||||
-rw-r--r-- | drivers/cxl/cxlmem.h | 15 | ||||
-rw-r--r-- | drivers/cxl/security.c | 22 | ||||
-rw-r--r-- | include/uapi/linux/cxl_mem.h | 1 |
4 files changed, 39 insertions, 0 deletions
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 6907ee1f43e0..2fdafa697e6a 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -66,6 +66,7 @@ static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = { CXL_CMD(SCAN_MEDIA, 0x11, 0, 0), CXL_CMD(GET_SCAN_MEDIA, 0, CXL_VARIABLE_PAYLOAD, 0), CXL_CMD(GET_SECURITY_STATE, 0, 0x4, 0), + CXL_CMD(SET_PASSPHRASE, 0x60, 0, 0), }; /* diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 25d1d8fa7d1e..725b08148524 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -274,6 +274,7 @@ enum cxl_opcode { CXL_MBOX_OP_SCAN_MEDIA = 0x4304, CXL_MBOX_OP_GET_SCAN_MEDIA = 0x4305, CXL_MBOX_OP_GET_SECURITY_STATE = 0x4500, + CXL_MBOX_OP_SET_PASSPHRASE = 0x4501, CXL_MBOX_OP_MAX = 0x10000 }; @@ -380,6 +381,20 @@ struct cxl_mem_command { #define CXL_PMEM_SEC_STATE_USER_PLIMIT 0x10 #define CXL_PMEM_SEC_STATE_MASTER_PLIMIT 0x20 +/* set passphrase input payload */ +struct cxl_set_pass { + u8 type; + u8 reserved[31]; + /* CXL field using NVDIMM define, same length */ + u8 old_pass[NVDIMM_PASSPHRASE_LEN]; + u8 new_pass[NVDIMM_PASSPHRASE_LEN]; +} __packed; + +enum { + CXL_PMEM_SEC_PASS_MASTER = 0, + CXL_PMEM_SEC_PASS_USER, +}; + int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in, size_t in_size, void *out, size_t out_size); int cxl_dev_state_identify(struct cxl_dev_state *cxlds); diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c index 806173084216..5365646230c3 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -49,8 +49,30 @@ static unsigned long cxl_pmem_get_security_flags(struct nvdimm *nvdimm, return security_flags; } +static int cxl_pmem_security_change_key(struct nvdimm *nvdimm, + const struct nvdimm_key_data *old_data, + const struct nvdimm_key_data *new_data, + enum nvdimm_passphrase_type ptype) +{ + struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); + struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; + struct cxl_dev_state *cxlds = cxlmd->cxlds; + struct cxl_set_pass set_pass; + int rc; + + set_pass.type = ptype == NVDIMM_MASTER ? + CXL_PMEM_SEC_PASS_MASTER : CXL_PMEM_SEC_PASS_USER; + memcpy(set_pass.old_pass, old_data->data, NVDIMM_PASSPHRASE_LEN); + memcpy(set_pass.new_pass, new_data->data, NVDIMM_PASSPHRASE_LEN); + + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_SET_PASSPHRASE, + &set_pass, sizeof(set_pass), NULL, 0); + return rc; +} + static const struct nvdimm_security_ops __cxl_security_ops = { .get_flags = cxl_pmem_get_security_flags, + .change_key = cxl_pmem_security_change_key, }; const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; diff --git a/include/uapi/linux/cxl_mem.h b/include/uapi/linux/cxl_mem.h index cdc6049683ce..9da047e9b038 100644 --- a/include/uapi/linux/cxl_mem.h +++ b/include/uapi/linux/cxl_mem.h @@ -42,6 +42,7 @@ ___C(SCAN_MEDIA, "Scan Media"), \ ___C(GET_SCAN_MEDIA, "Get Scan Media Results"), \ ___C(GET_SECURITY_STATE, "Get Security State"), \ + ___C(SET_PASSPHRASE, "Set Passphrase"), \ ___C(MAX, "invalid / last command") #define ___C(a, b) CXL_MEM_COMMAND_ID_##a |