mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
37833fb798
Add support for freeze security on Intel nvdimm. This locks out any changes to security for the DIMM until a hard reset of the DIMM is performed. This is triggered by writing "freeze" to the generic nvdimm/nmemX "security" sysfs attribute. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Co-developed-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
83 lines
2.2 KiB
C
83 lines
2.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright(c) 2018 Intel Corporation. All rights reserved. */
|
|
#include <linux/libnvdimm.h>
|
|
#include <linux/ndctl.h>
|
|
#include <linux/acpi.h>
|
|
#include "intel.h"
|
|
#include "nfit.h"
|
|
|
|
static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm)
|
|
{
|
|
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
|
|
struct {
|
|
struct nd_cmd_pkg pkg;
|
|
struct nd_intel_get_security_state cmd;
|
|
} nd_cmd = {
|
|
.pkg = {
|
|
.nd_command = NVDIMM_INTEL_GET_SECURITY_STATE,
|
|
.nd_family = NVDIMM_FAMILY_INTEL,
|
|
.nd_size_out =
|
|
sizeof(struct nd_intel_get_security_state),
|
|
.nd_fw_size =
|
|
sizeof(struct nd_intel_get_security_state),
|
|
},
|
|
};
|
|
int rc;
|
|
|
|
if (!test_bit(NVDIMM_INTEL_GET_SECURITY_STATE, &nfit_mem->dsm_mask))
|
|
return -ENXIO;
|
|
|
|
rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
|
|
if (rc < 0)
|
|
return rc;
|
|
if (nd_cmd.cmd.status)
|
|
return -EIO;
|
|
|
|
/* check and see if security is enabled and locked */
|
|
if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED)
|
|
return -ENXIO;
|
|
else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) {
|
|
if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_LOCKED)
|
|
return NVDIMM_SECURITY_LOCKED;
|
|
else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN ||
|
|
nd_cmd.cmd.state & ND_INTEL_SEC_STATE_PLIMIT)
|
|
return NVDIMM_SECURITY_FROZEN;
|
|
else
|
|
return NVDIMM_SECURITY_UNLOCKED;
|
|
}
|
|
return NVDIMM_SECURITY_DISABLED;
|
|
}
|
|
|
|
static int intel_security_freeze(struct nvdimm *nvdimm)
|
|
{
|
|
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
|
|
struct {
|
|
struct nd_cmd_pkg pkg;
|
|
struct nd_intel_freeze_lock cmd;
|
|
} nd_cmd = {
|
|
.pkg = {
|
|
.nd_command = NVDIMM_INTEL_FREEZE_LOCK,
|
|
.nd_family = NVDIMM_FAMILY_INTEL,
|
|
.nd_size_out = ND_INTEL_STATUS_SIZE,
|
|
.nd_fw_size = ND_INTEL_STATUS_SIZE,
|
|
},
|
|
};
|
|
int rc;
|
|
|
|
if (!test_bit(NVDIMM_INTEL_FREEZE_LOCK, &nfit_mem->dsm_mask))
|
|
return -ENOTTY;
|
|
|
|
rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
|
|
if (rc < 0)
|
|
return rc;
|
|
if (nd_cmd.cmd.status)
|
|
return -EIO;
|
|
return 0;
|
|
}
|
|
|
|
static const struct nvdimm_security_ops __intel_security_ops = {
|
|
.state = intel_security_state,
|
|
.freeze = intel_security_freeze,
|
|
};
|
|
const struct nvdimm_security_ops *intel_security_ops = &__intel_security_ops;
|