mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
cxl/pmem: Introduce nvdimm_security_ops with ->get_flags() operation
Add nvdimm_security_ops support for CXL memory device with the introduction of the ->get_flags() callback function. This is part of the "Persistent Memory Data-at-rest Security" command set for CXL memory device support. The ->get_flags() function provides the security state of the persistent memory device defined by the CXL 3.0 spec section 8.2.9.8.6.1. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/166983609611.2734609.13231854299523325319.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
3b39fd6cf1
commit
3282811555
@ -9,5 +9,5 @@ obj-$(CONFIG_CXL_PORT) += cxl_port.o
|
||||
cxl_mem-y := mem.o
|
||||
cxl_pci-y := pci.o
|
||||
cxl_acpi-y := acpi.o
|
||||
cxl_pmem-y := pmem.o
|
||||
cxl_pmem-y := pmem.o security.o
|
||||
cxl_port-y := port.o
|
||||
|
@ -65,6 +65,7 @@ static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = {
|
||||
CXL_CMD(GET_SCAN_MEDIA_CAPS, 0x10, 0x4, 0),
|
||||
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),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -273,6 +273,7 @@ enum cxl_opcode {
|
||||
CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS = 0x4303,
|
||||
CXL_MBOX_OP_SCAN_MEDIA = 0x4304,
|
||||
CXL_MBOX_OP_GET_SCAN_MEDIA = 0x4305,
|
||||
CXL_MBOX_OP_GET_SECURITY_STATE = 0x4500,
|
||||
CXL_MBOX_OP_MAX = 0x10000
|
||||
};
|
||||
|
||||
@ -372,6 +373,13 @@ struct cxl_mem_command {
|
||||
#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0)
|
||||
};
|
||||
|
||||
#define CXL_PMEM_SEC_STATE_USER_PASS_SET 0x01
|
||||
#define CXL_PMEM_SEC_STATE_MASTER_PASS_SET 0x02
|
||||
#define CXL_PMEM_SEC_STATE_LOCKED 0x04
|
||||
#define CXL_PMEM_SEC_STATE_FROZEN 0x08
|
||||
#define CXL_PMEM_SEC_STATE_USER_PLIMIT 0x10
|
||||
#define CXL_PMEM_SEC_STATE_MASTER_PLIMIT 0x20
|
||||
|
||||
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);
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "cxlmem.h"
|
||||
#include "cxl.h"
|
||||
|
||||
extern const struct nvdimm_security_ops *cxl_security_ops;
|
||||
|
||||
/*
|
||||
* Ordered workqueue for cxl nvdimm device arrival and departure
|
||||
* to coordinate bus rescans when a bridge arrives and trigger remove
|
||||
@ -78,8 +80,8 @@ static int cxl_nvdimm_probe(struct device *dev)
|
||||
set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask);
|
||||
set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask);
|
||||
set_bit(ND_CMD_SET_CONFIG_DATA, &cmd_mask);
|
||||
nvdimm = nvdimm_create(cxl_nvb->nvdimm_bus, cxl_nvd, NULL, flags,
|
||||
cmd_mask, 0, NULL);
|
||||
nvdimm = __nvdimm_create(cxl_nvb->nvdimm_bus, cxl_nvd, NULL, flags,
|
||||
cmd_mask, 0, NULL, NULL, cxl_security_ops, NULL);
|
||||
if (!nvdimm) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
|
56
drivers/cxl/security.c
Normal file
56
drivers/cxl/security.c
Normal file
@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
|
||||
#include <linux/libnvdimm.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/async.h>
|
||||
#include <linux/slab.h>
|
||||
#include "cxlmem.h"
|
||||
#include "cxl.h"
|
||||
|
||||
static unsigned long cxl_pmem_get_security_flags(struct nvdimm *nvdimm,
|
||||
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;
|
||||
unsigned long security_flags = 0;
|
||||
u32 sec_out;
|
||||
int rc;
|
||||
|
||||
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_SECURITY_STATE, NULL, 0,
|
||||
&sec_out, sizeof(sec_out));
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
|
||||
if (ptype == NVDIMM_MASTER) {
|
||||
if (sec_out & CXL_PMEM_SEC_STATE_MASTER_PASS_SET)
|
||||
set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags);
|
||||
else
|
||||
set_bit(NVDIMM_SECURITY_DISABLED, &security_flags);
|
||||
if (sec_out & CXL_PMEM_SEC_STATE_MASTER_PLIMIT)
|
||||
set_bit(NVDIMM_SECURITY_FROZEN, &security_flags);
|
||||
return security_flags;
|
||||
}
|
||||
|
||||
if (sec_out & CXL_PMEM_SEC_STATE_USER_PASS_SET) {
|
||||
if (sec_out & CXL_PMEM_SEC_STATE_FROZEN ||
|
||||
sec_out & CXL_PMEM_SEC_STATE_USER_PLIMIT)
|
||||
set_bit(NVDIMM_SECURITY_FROZEN, &security_flags);
|
||||
|
||||
if (sec_out & CXL_PMEM_SEC_STATE_LOCKED)
|
||||
set_bit(NVDIMM_SECURITY_LOCKED, &security_flags);
|
||||
else
|
||||
set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags);
|
||||
} else {
|
||||
set_bit(NVDIMM_SECURITY_DISABLED, &security_flags);
|
||||
}
|
||||
|
||||
return security_flags;
|
||||
}
|
||||
|
||||
static const struct nvdimm_security_ops __cxl_security_ops = {
|
||||
.get_flags = cxl_pmem_get_security_flags,
|
||||
};
|
||||
|
||||
const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops;
|
@ -41,6 +41,7 @@
|
||||
___C(GET_SCAN_MEDIA_CAPS, "Get Scan Media Capabilities"), \
|
||||
___C(SCAN_MEDIA, "Scan Media"), \
|
||||
___C(GET_SCAN_MEDIA, "Get Scan Media Results"), \
|
||||
___C(GET_SECURITY_STATE, "Get Security State"), \
|
||||
___C(MAX, "invalid / last command")
|
||||
|
||||
#define ___C(a, b) CXL_MEM_COMMAND_ID_##a
|
||||
|
@ -26,6 +26,7 @@ cxl_acpi-y += config_check.o
|
||||
obj-m += cxl_pmem.o
|
||||
|
||||
cxl_pmem-y := $(CXL_SRC)/pmem.o
|
||||
cxl_pmem-y += $(CXL_SRC)/security.o
|
||||
cxl_pmem-y += config_check.o
|
||||
|
||||
obj-m += cxl_port.o
|
||||
|
Loading…
Reference in New Issue
Block a user