From patchwork Fri Jul 15 21:08:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919717 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E18C15382 for ; Fri, 15 Jul 2022 21:08:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919319; x=1689455319; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9rZTNHLSztiH0nN2cBKzyjZJ5yqEsukWe+x5YDaSmq0=; b=gb75SWyW81Rgha0n+K73l3SQJbh/AxeRAhj1FNU90Qas8CzClhFHNrr2 bBsTznbW52C3F6Dgy2L5jeJUx4hbdDElKn2f9J7C8L8sJ6Hg34/ydgj9A GZF7AyyL570PaCOmUGNptnKIiwVX6Sp4DoALPg9ugbDQ1G/gNJ0ekYgLL r1XbUhkMSf750r8dfbVwkTkDo2E9GQ3O8jpwdT4pw391+h4J9YVZKePdy SWTWYxGmRBevdOG7So8KYk9hs9n1jCW3DN2NC17ZyIe4cyAh9DrPD30wJ xew8IjQKyvXdk3SVW9/9XLHpCHrYBLI63M90jeJBGpV1aNGnOTmcMMIbC w==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="372214980" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="372214980" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:08:39 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="596605664" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:08:38 -0700 Subject: [PATCH RFC 01/15] cxl/pmem: Introduce nvdimm_security_ops with ->get_flags() operation From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:08:38 -0700 Message-ID: <165791931828.2491387.3280104860123759941.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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 2.0 spec section 8.2.9.5.6.1. The nvdimm_security_ops for CXL is configured as an build option toggled by kernel configuration CONFIG_CXL_PMEM_SECURITY. Signed-off-by: Dave Jiang Reviewed-by: Jonathan Cameron --- drivers/cxl/Kconfig | 16 +++++++++++++ drivers/cxl/Makefile | 1 + drivers/cxl/cxlmem.h | 9 +++++++ drivers/cxl/pmem.c | 10 ++++++-- drivers/cxl/security.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++ tools/testing/cxl/Kbuild | 1 + 6 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 drivers/cxl/security.c diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig index f64e3984689f..43527a697f60 100644 --- a/drivers/cxl/Kconfig +++ b/drivers/cxl/Kconfig @@ -102,4 +102,20 @@ config CXL_SUSPEND def_bool y depends on SUSPEND && CXL_MEM +config CXL_PMEM_SECURITY + tristate "CXL PMEM SECURITY: Persistent Memory Security Support" + depends on CXL_PMEM + default CXL_BUS + help + CXL memory device "Persistent Memory Data-at-rest Security" command set + support. Support opcode 0x4500..0x4505. The commands supported are "Get + Security State", "Set Passphrase", "Disable Passphrase", "Unlock", + "Freeze Security State", and "Passphrase Secure Erase". Security operation + is done through nvdimm security_ops. + + See Chapter 8.2.9.5.6 in the CXL 2.0 specification for a detailed description + of the Persistent Memory Security. + + If unsure say 'm'. + endif diff --git a/drivers/cxl/Makefile b/drivers/cxl/Makefile index a78270794150..c19cf28f7512 100644 --- a/drivers/cxl/Makefile +++ b/drivers/cxl/Makefile @@ -11,3 +11,4 @@ cxl_pci-y := pci.o cxl_acpi-y := acpi.o cxl_pmem-y := pmem.o cxl_port-y := port.o +cxl_pmem-$(CONFIG_CXL_PMEM_SECURITY) += security.o diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 7df0b053373a..35de2889aac3 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -250,6 +250,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 }; @@ -342,6 +343,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); @@ -370,4 +378,5 @@ struct cxl_hdm { unsigned int interleave_mask; struct cxl_port *port; }; + #endif /* __CXL_MEM_H__ */ diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c index 0aaa70b4e0f7..6dbf067dcf10 100644 --- a/drivers/cxl/pmem.c +++ b/drivers/cxl/pmem.c @@ -10,6 +10,12 @@ #include "cxlmem.h" #include "cxl.h" +#if IS_ENABLED(CONFIG_CXL_PMEM_SECURITY) +extern const struct nvdimm_security_ops *cxl_security_ops; +#else +static const struct nvdimm_security_ops *cxl_security_ops = NULL; +#endif + /* * Ordered workqueue for cxl nvdimm device arrival and departure * to coordinate bus rescans when a bridge arrives and trigger remove @@ -58,8 +64,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; diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c new file mode 100644 index 000000000000..5b830ae621db --- /dev/null +++ b/drivers/cxl/security.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. All rights reserved. */ +#include +#include +#include +#include +#include +#include +#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; + 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; diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild index 33543231d453..7db7a35a1c2a 100644 --- a/tools/testing/cxl/Kbuild +++ b/tools/testing/cxl/Kbuild @@ -27,6 +27,7 @@ obj-m += cxl_pmem.o cxl_pmem-y := $(CXL_SRC)/pmem.o cxl_pmem-y += config_check.o +cxl_pmem-$(CONFIG_CXL_PMEM_SECURITY) += $(CXL_SRC)/security.o obj-m += cxl_port.o From patchwork Fri Jul 15 21:08:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919718 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED8755381 for ; Fri, 15 Jul 2022 21:08:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919326; x=1689455326; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5RHeJXI/DSKBOwxq0dyffmzXTzBt+vgqLxC2bhkenCQ=; b=GkqvSDolcawHpelXx96ABpTYXL0FTyUK3/Af6YUKjSdNXN8w4hW4c1BP EvOgc26FM32rEydNx+uf4irhUTq55e2tEsUzvioPzcEPtHLL1fIihd2WO 25mhCoHzgssEJLK5cW9AKcXeels5sJ1WAFGJTh7HJC7+BxFDbk3B6KKwL ybbBI3novznUxjSigqIP4z0/DGqA34Aukjlw+e48QnkbutVMC7I0SHNKp +O+XxFDtPrCo94OXM6gZsCDsqtLMh91e/Fj+NJz1uMXpA6gHdkfHF95PQ n1W5b1HBk0LUFBe3TJylVbwGwGzPdO/6lQ+65LlC0oIbUPABmCu8E32dH g==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="285927292" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="285927292" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:08:46 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="923658642" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:08:44 -0700 Subject: [PATCH RFC 02/15] tools/testing/cxl: Create context for cxl mock device From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:08:44 -0700 Message-ID: <165791932409.2491387.9065856569307593223.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add context struct for mock device and move lsa under the context. This allows additional information such as security status and other persistent security data such as passphrase to be added for the emulated test device. Signed-off-by: Dave Jiang Reviewed-by: Davidlohr Bueso --- tools/testing/cxl/test/mem.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 6b9239b2afd4..723378248321 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -9,6 +9,10 @@ #include #include +struct mock_mdev_data { + void *lsa; +}; + #define LSA_SIZE SZ_128K #define EFFECT(x) (1U << x) @@ -140,7 +144,8 @@ static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in; - void *lsa = dev_get_drvdata(cxlds->dev); + struct mock_mdev_data *mdata = dev_get_drvdata(cxlds->dev); + void *lsa = mdata->lsa; u32 offset, length; if (sizeof(*get_lsa) > cmd->size_in) @@ -159,7 +164,8 @@ static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) static int mock_set_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_set_lsa *set_lsa = cmd->payload_in; - void *lsa = dev_get_drvdata(cxlds->dev); + struct mock_mdev_data *mdata = dev_get_drvdata(cxlds->dev); + void *lsa = mdata->lsa; u32 offset, length; if (sizeof(*set_lsa) > cmd->size_in) @@ -237,9 +243,12 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * return rc; } -static void label_area_release(void *lsa) +static void cxl_mock_drvdata_release(void *data) { - vfree(lsa); + struct mock_mdev_data *mdata = data; + + vfree(mdata->lsa); + vfree(mdata); } static int cxl_mock_mem_probe(struct platform_device *pdev) @@ -247,13 +256,21 @@ static int cxl_mock_mem_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct cxl_memdev *cxlmd; struct cxl_dev_state *cxlds; + struct mock_mdev_data *mdata; void *lsa; int rc; + mdata = vmalloc(sizeof(*mdata)); + if (!mdata) + return -ENOMEM; + lsa = vmalloc(LSA_SIZE); - if (!lsa) + if (!lsa) { + vfree(mdata); return -ENOMEM; - rc = devm_add_action_or_reset(dev, label_area_release, lsa); + } + + rc = devm_add_action_or_reset(dev, cxl_mock_drvdata_release, mdata); if (rc) return rc; dev_set_drvdata(dev, lsa); From patchwork Fri Jul 15 21:08:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919719 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DAD465381 for ; Fri, 15 Jul 2022 21:08:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919330; x=1689455330; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fZzS0dNQqzNeoZ9itlm7J1mbGFqBsFU+AxSoJ/hpTPw=; b=EWnnpKqpJoSk0aWmszZ5KwBes4c0STY4ISSLQwsRQNZnfAG1QNdByGph L0UkR1G/xPzlj6hV5zLDMu3vW796sGIMApDoi66+XFx+7ec8Khr49PMWZ MrB6n9MENNoJkfx5PFpp2feALVQAct6e9KLk6KCvvgAaFLAx11vbHwK4a b/Ga0gBXQkxq768Lu4rQgZADtUameJ7Lkg2WSrf39gdBu1vW01F+A/7ji qOCgU6hKxL9UjV/8ettkQWXr9k3LpxsfBIkPgWNYaTelfMXYi8R7JAbQn PC8qxRhcGX00GSzsseCRcDtEcOD6abp/31X/7oitmkWNnfnfICK8L33Mp Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="349863156" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="349863156" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:08:50 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="546797585" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:08:50 -0700 Subject: [PATCH RFC 03/15] tools/testing/cxl: Add "Get Security State" opcode support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:08:49 -0700 Message-ID: <165791932983.2491387.13708346830998415266.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the emulation support for handling "Get Security State" opcode for a CXL memory device for the cxl_test. The function will copy back device security state bitmask to the output payload. Signed-off-by: Dave Jiang --- tools/testing/cxl/test/mem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 723378248321..337e5a099d31 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -11,6 +11,7 @@ struct mock_mdev_data { void *lsa; + u32 security_state; }; #define LSA_SIZE SZ_128K @@ -141,6 +142,26 @@ static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) return 0; } +static int mock_get_security_state(struct cxl_dev_state *cxlds, + struct cxl_mbox_cmd *cmd) +{ + struct mock_mdev_data *mdata = dev_get_drvdata(cxlds->dev); + + if (cmd->size_in) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (cmd->size_out != sizeof(u32)) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + memcpy(cmd->payload_out, &mdata->security_state, sizeof(u32)); + + return 0; +} + static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in; @@ -233,6 +254,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_GET_HEALTH_INFO: rc = mock_health_info(cxlds, cmd); break; + case CXL_MBOX_OP_GET_SECURITY_STATE: + rc = mock_get_security_state(cxlds, cmd); + break; default: break; } From patchwork Fri Jul 15 21:08:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919720 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E0055381 for ; Fri, 15 Jul 2022 21:08:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919337; x=1689455337; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UTg2OVhCAgGBjenPtHjfpLVSV12FtAaPcU6oPUV5O/U=; b=CHxqMvuMQuk1QYZlDaDuSEWDPjO4rx9NXy8g8joMtykWNRs250MUsR+2 +Hd1HPPc4/WsmyITp+id5fpAnEF6AiyPqRKTasxkbpqGZSz/PsvmbOKY+ YyJfApF/vfsuZ5YGV+o8QYulnRrsi0W9lgfUOi8CbA59R4xKV6HREnHIW qRMkPphbQ6EG37hQb1eLJcllQnJdbiMy06ekd2w8JfqVxR6QYwzbCvWBe fSCLJMLAyrH7rdET1RHkIZLuQ3Jg1dTPXSvtegrVyZH7auECyy+lsdT2j 1ik79v++J8X94+7Y4R7iUtM63eR/Ebz9YuxxBR/7Q5NyYq3dE9N0bgKHG g==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="372215037" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="372215037" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:08:56 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="593873333" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:08:55 -0700 Subject: [PATCH RFC 04/15] cxl/pmem: Add "Set Passphrase" security command support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:08:55 -0700 Message-ID: <165791933557.2491387.2141316283759403219.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Create callback function to support the nvdimm_security_ops ->change_key() callback. Translate the operation to send "Set Passphrase" security command for CXL memory device. The operation supports setting a passphrase for the CXL persistent memory device. It also supports the changing of the currently set passphrase. The operation allows manipulation of a user passphrase or a master passphrase. See CXL 2.0 spec section 8.2.9.5.6.2 for reference. However, the spec leaves a gap WRT master passphrase usages. The spec does not define any ways to retrieve the status of if the support of master passphrase is available for the device, nor does the commands that utilize master passphrase will return a specific error that indicates master passphrase is not supported. If using a device does not support master passphrase and a command is issued with a master passphrase, the error message returned by the device will be ambiguos. Signed-off-by: Dave Jiang Reviewed-by: Jonathan Cameron --- drivers/cxl/cxlmem.h | 14 ++++++++++++++ drivers/cxl/security.c | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 35de2889aac3..1e76d22f4fd2 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -251,6 +251,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 }; @@ -350,6 +351,19 @@ 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]; + 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 5b830ae621db..76ec5087f966 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -50,8 +50,35 @@ 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 = kzalloc(sizeof(*set_pass), GFP_KERNEL); + if (!set_pass) + return -ENOMEM; + + 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); + kfree(set_pass); + 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; From patchwork Fri Jul 15 21:09:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919721 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D4435381 for ; Fri, 15 Jul 2022 21:09:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919342; x=1689455342; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=x/w4rjZNzfd3oOdRpIA4+Gm9z+kuyHAk+EzXG7r/RqQ=; b=CBsCRgHl0R5dN4BUlv1hRvEn4beouhwb5shYnNGZXpFgW1MsXKj242LA 6XR7EleVy27kMJzk9bhDwTwHN3//5g74Cxp2sFQsNA7LMmc+0o7aziXMX UkvtZnIj6FY5IN5BRONhqjUlxd3IAVFjLE2Ms7upV90cR9kBBkkg/okLs E7kzJBOMBAzUuUygGga1/XdpIRZncGOaot+rHZeaqnVx++NuGKgAC/ycZ uBWZGFlLlMDSBSyMLoS5ihcQGMhvtkkgnlT6JBpCZBU4jDayQom36RH5h QXxvDclLsdgKycMcmVlYl9oTIFz0VcKxaiHcGFsdVUioJnd66Ob3wM6tf g==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="283458360" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="283458360" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:02 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="654501327" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:01 -0700 Subject: [PATCH RFC 05/15] tools/testing/cxl: Add "Set Passphrase" opcode support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:01 -0700 Message-ID: <165791934143.2491387.18407792819271591669.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support to emulate a CXL mem device supporting the "Set Passphrase" operation. The operation supports setting of either a user or a master passphrase. Signed-off-by: Dave Jiang --- tools/testing/cxl/test/mem.c | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 337e5a099d31..796f4f7b5e3d 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -12,8 +12,14 @@ struct mock_mdev_data { void *lsa; u32 security_state; + u8 user_pass[NVDIMM_PASSPHRASE_LEN]; + u8 master_pass[NVDIMM_PASSPHRASE_LEN]; + int user_limit; + int master_limit; }; +#define PASS_TRY_LIMIT 3 + #define LSA_SIZE SZ_128K #define EFFECT(x) (1U << x) @@ -162,6 +168,73 @@ static int mock_get_security_state(struct cxl_dev_state *cxlds, return 0; } +static int mock_set_passphrase(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) +{ + struct mock_mdev_data *mdata = dev_get_drvdata(cxlds->dev); + struct cxl_set_pass *set_pass; + + if (cmd->size_in != sizeof(*set_pass)) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (cmd->size_out != 0) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (mdata->security_state & CXL_PMEM_SEC_STATE_FROZEN) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + set_pass = cmd->payload_in; + switch (set_pass->type) { + case CXL_PMEM_SEC_PASS_MASTER: + if (mdata->security_state & CXL_PMEM_SEC_STATE_MASTER_PLIMIT) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + /* + * CXL spec v2.0 8.2.9.5.6.2, The master pasphrase shall only be set in + * the security disabled state when the user passphrase is not set. + */ + if (mdata->security_state & CXL_PMEM_SEC_STATE_USER_PASS_SET) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + if (mdata->security_state & CXL_PMEM_SEC_STATE_MASTER_PASS_SET && + memcmp(mdata->master_pass, set_pass->old_pass, NVDIMM_PASSPHRASE_LEN)) { + if (++mdata->master_limit == PASS_TRY_LIMIT) + mdata->security_state |= CXL_PMEM_SEC_STATE_MASTER_PLIMIT; + cmd->return_code = CXL_MBOX_CMD_RC_PASSPHRASE; + return -ENXIO; + } + memcpy(mdata->master_pass, set_pass->new_pass, NVDIMM_PASSPHRASE_LEN); + break; + + case CXL_PMEM_SEC_PASS_USER: + if (mdata->security_state & CXL_PMEM_SEC_STATE_USER_PLIMIT) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + if (mdata->security_state & CXL_PMEM_SEC_STATE_USER_PASS_SET && + memcmp(mdata->user_pass, set_pass->old_pass, NVDIMM_PASSPHRASE_LEN)) { + if (++mdata->user_limit == PASS_TRY_LIMIT) + mdata->security_state |= CXL_PMEM_SEC_STATE_USER_PLIMIT; + cmd->return_code = CXL_MBOX_CMD_RC_PASSPHRASE; + return -ENXIO; + } + memcpy(mdata->user_pass, set_pass->new_pass, NVDIMM_PASSPHRASE_LEN); + break; + + default: + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + return 0; +} + static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in; @@ -257,6 +330,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_GET_SECURITY_STATE: rc = mock_get_security_state(cxlds, cmd); break; + case CXL_MBOX_OP_SET_PASSPHRASE: + rc = mock_set_passphrase(cxlds, cmd); + break; default: break; } From patchwork Fri Jul 15 21:09:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919722 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3EB435381 for ; Fri, 15 Jul 2022 21:09:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919348; x=1689455348; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dBQENS3znweCF0yiR8zGCtWQ5lG/ElS4TNT6oglovdw=; b=JyLgtx98eLOxZXnjRgBOsvGGXZOCBHVWQkver2h1dfeNC8ueU0RgLZmL nu1fQCgIyyS9hY39hjum9oL2HCBZLuOHr3RVQv4Lyk+sVF3mca+LxtTCp 5WHGgIqvuL4O6Ym+n3KknuhGerLPfCtaPLrReXIFV/3SgDkOPRAOwo04R hh0V/t/M1B7BhqkdzOsuuws3z9czS9in6pggduEjOMJbW+XBrDwCzaM5N jfifx3OdrQDCfD168yHUuPPeLvmHj+0ANSmWykP3ymtPYuoFWtTEsLRqO kv9c0bef7xqENwrLbrHGj3VuKcWuFmcnM7reQU/5tzLJznKYVcIbjpr5H A==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="283458383" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="283458383" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:08 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="629248825" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:07 -0700 Subject: [PATCH RFC 06/15] cxl/pmem: Add Disable Passphrase security command support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:07 -0700 Message-ID: <165791934720.2491387.11236603584810515256.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Create callback function to support the nvdimm_security_ops ->disable() callback. Translate the operation to send "Disable Passphrase" security command for CXL memory device. The operation supports disabling a passphrase for the CXL persistent memory device. In the original implementation of nvdimm_security_ops, this operation only supports disabling of the user passphrase. This is due to the NFIT version of disable passphrase only supported disabling of user passphrase. The CXL spec allows disabling of the master passphrase as well which nvidmm_security_ops does not support yet. In this commit, the callback function will only support user passphrase. See CXL 2.0 spec section 8.2.9.5.6.3 for reference. Signed-off-by: Dave Jiang Reviewed-by: Jonathan Cameron --- drivers/cxl/cxlmem.h | 8 ++++++++ drivers/cxl/security.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 1e76d22f4fd2..70a1eb7720d3 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -252,6 +252,7 @@ enum cxl_opcode { CXL_MBOX_OP_GET_SCAN_MEDIA = 0x4305, CXL_MBOX_OP_GET_SECURITY_STATE = 0x4500, CXL_MBOX_OP_SET_PASSPHRASE = 0x4501, + CXL_MBOX_OP_DISABLE_PASSPHRASE = 0x4502, CXL_MBOX_OP_MAX = 0x10000 }; @@ -359,6 +360,13 @@ struct cxl_set_pass { u8 new_pass[NVDIMM_PASSPHRASE_LEN]; } __packed; +/* disable passphrase input payload */ +struct cxl_disable_pass { + u8 type; + u8 reserved[31]; + u8 pass[NVDIMM_PASSPHRASE_LEN]; +} __packed; + enum { CXL_PMEM_SEC_PASS_MASTER = 0, CXL_PMEM_SEC_PASS_USER, diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c index 76ec5087f966..4aec8e41e167 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -76,9 +76,39 @@ static int cxl_pmem_security_change_key(struct nvdimm *nvdimm, return rc; } +static int cxl_pmem_security_disable(struct nvdimm *nvdimm, + const struct nvdimm_key_data *key_data) +{ + 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_disable_pass *dis_pass; + int rc; + + dis_pass = kzalloc(sizeof(*dis_pass), GFP_KERNEL); + if (!dis_pass) + return -ENOMEM; + + /* + * While the CXL spec defines the ability to erase the master passphrase, + * the original nvdimm security ops does not provide that capability. + * In order to preserve backward compatibility, this callback will + * only support disable of user passphrase. The disable master passphrase + * ability will need to be added as a new callback. + */ + dis_pass->type = CXL_PMEM_SEC_PASS_USER; + memcpy(dis_pass->pass, key_data->data, NVDIMM_PASSPHRASE_LEN); + + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_DISABLE_PASSPHRASE, + dis_pass, sizeof(*dis_pass), NULL, 0); + kfree(dis_pass); + 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, + .disable = cxl_pmem_security_disable, }; const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; From patchwork Fri Jul 15 21:09:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919723 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0290A5381 for ; Fri, 15 Jul 2022 21:09:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919353; x=1689455353; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=AmRKgFBgyiPqG7OL7LtVwwfafKuadNDkkCfVrQRh8TE=; b=g1lc0GljrfcMZ5gQlbmEiBAH+51jas8Cs3RX0+ZcBUAZ53bSq+rJwljU zOGyLEz62Qbfv4jnKnrMtDEq0Y6Ih2cg2xO5w33IqQcqYt33HHdV2+mhS WIJ18ekQOMD0Xx+EIQn12EYM2MftatztP3nmQCg7o1OG+8m9B9lsKCK53 wM5YSaLh/IpGSxojZNsYUisBJgc1E1LRHEFpuEZV+DCmCej9iyfS2W3Tr nEWnXAyq7bLxLGNSvo2Rxx1HtLA93HtLpxJrGJ96CFP5Hkj9Cp53uz+ZO FPpbN2BiRMdy4/Y6jFmH/nx2/gtiQfuQw68WKR9I/pt0JhYgKMTpOdHtg w==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="268921489" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="268921489" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:13 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="571680678" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:13 -0700 Subject: [PATCH RFC 07/15] tools/testing/cxl: Add "Disable" security opcode support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:12 -0700 Message-ID: <165791935297.2491387.8950514630973579122.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support to emulate a CXL mem device support the "Disable Passphrase" operation. The operation supports disabling of either a user or a master passphrase. The emulation will provide support for both user and master passphrase. Signed-off-by: Dave Jiang --- tools/testing/cxl/test/mem.c | 80 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 796f4f7b5e3d..5f87a94d92ae 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -235,6 +235,83 @@ static int mock_set_passphrase(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd return 0; } +static int mock_disable_passphrase(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) +{ + struct mock_mdev_data *mdata = dev_get_drvdata(cxlds->dev); + struct cxl_disable_pass *dis_pass; + + if (cmd->size_in != sizeof(*dis_pass)) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (cmd->size_out != 0) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (mdata->security_state & CXL_PMEM_SEC_STATE_FROZEN) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + dis_pass = cmd->payload_in; + switch (dis_pass->type) { + case CXL_PMEM_SEC_PASS_MASTER: + if (mdata->security_state & CXL_PMEM_SEC_STATE_MASTER_PLIMIT) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (!(mdata->security_state & CXL_PMEM_SEC_STATE_MASTER_PASS_SET)) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (memcmp(dis_pass->pass, mdata->master_pass, NVDIMM_PASSPHRASE_LEN)) { + if (++mdata->master_limit == PASS_TRY_LIMIT) + mdata->security_state |= CXL_PMEM_SEC_STATE_MASTER_PLIMIT; + cmd->return_code = CXL_MBOX_CMD_RC_PASSPHRASE; + return -ENXIO; + } + + mdata->master_limit = 0; + memset(mdata->master_pass, 0, NVDIMM_PASSPHRASE_LEN); + mdata->security_state &= ~CXL_PMEM_SEC_STATE_MASTER_PASS_SET; + break; + + case CXL_PMEM_SEC_PASS_USER: + if (mdata->security_state & CXL_PMEM_SEC_STATE_USER_PLIMIT) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (!(mdata->security_state & CXL_PMEM_SEC_STATE_USER_PASS_SET)) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (memcmp(dis_pass->pass, mdata->user_pass, NVDIMM_PASSPHRASE_LEN)) { + if (++mdata->user_limit == PASS_TRY_LIMIT) + mdata->security_state |= CXL_PMEM_SEC_STATE_USER_PLIMIT; + cmd->return_code = CXL_MBOX_CMD_RC_PASSPHRASE; + return -ENXIO; + } + + mdata->user_limit = 0; + memset(mdata->user_pass, 0, NVDIMM_PASSPHRASE_LEN); + mdata->security_state &= ~(CXL_PMEM_SEC_STATE_USER_PASS_SET | + CXL_PMEM_SEC_STATE_LOCKED); + break; + + default: + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + return 0; +} + static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in; @@ -333,6 +410,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_SET_PASSPHRASE: rc = mock_set_passphrase(cxlds, cmd); break; + case CXL_MBOX_OP_DISABLE_PASSPHRASE: + rc = mock_disable_passphrase(cxlds, cmd); + break; default: break; } From patchwork Fri Jul 15 21:09:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919724 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D75025381 for ; Fri, 15 Jul 2022 21:09:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919362; x=1689455362; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=r2aXZnpKaSzek4KrNak5pgYah4lSLSdXiEHloFx2LQg=; b=GM7lsnEURq8mjtdqsUxH38dM8Lis78doTPEU1zAY4UkvqqOBUCaTrKNb f4/POvpXkWSEMqtTLqUq6ambjalW/fQgH3umUumcJIg4/scN2o6nADv3U l1REc2R+8nuHjG4NJ6FtRaWP3+GZgskxQWRKIFpVCre+zCh/yKT0bMJcu pOQBGmUKKE4x2Yh9xWp/yaeqiYkorlktLTfy46WNzp+ceJGEdUGaOuJOw gSsGSXPT+v6Ht19WMafGd/j3odfnzB2z6zg+ZnZ/S0/VjGJs3gsaE+W2T LWJgOYlPdQZKUT0Q/Ba1gZWzaettB7Nq5O+GnQVraWqzilSuhYeybey3X Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="347587964" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="347587964" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:19 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="624010379" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:19 -0700 Subject: [PATCH RFC 08/15] cxl/pmem: Add "Freeze Security State" security command support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:18 -0700 Message-ID: <165791935875.2491387.542348076045531850.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Create callback function to support the nvdimm_security_ops() ->freeze() callback. Translate the operation to send "Freeze Security State" security command for CXL memory device. See CXL 2.0 spec section 8.2.9.5.6.5 for reference. Signed-off-by: Dave Jiang Reviewed-by: Jonathan Cameron --- drivers/cxl/cxlmem.h | 1 + drivers/cxl/security.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 70a1eb7720d3..ced85be291f3 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -253,6 +253,7 @@ enum cxl_opcode { CXL_MBOX_OP_GET_SECURITY_STATE = 0x4500, CXL_MBOX_OP_SET_PASSPHRASE = 0x4501, CXL_MBOX_OP_DISABLE_PASSPHRASE = 0x4502, + CXL_MBOX_OP_FREEZE_SECURITY = 0x4504, CXL_MBOX_OP_MAX = 0x10000 }; diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c index 4aec8e41e167..6399266a5908 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -105,10 +105,20 @@ static int cxl_pmem_security_disable(struct nvdimm *nvdimm, return rc; } +static int cxl_pmem_security_freeze(struct nvdimm *nvdimm) +{ + struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); + struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; + struct cxl_dev_state *cxlds = cxlmd->cxlds; + + return cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_FREEZE_SECURITY, NULL, 0, NULL, 0); +} + static const struct nvdimm_security_ops __cxl_security_ops = { .get_flags = cxl_pmem_get_security_flags, .change_key = cxl_pmem_security_change_key, .disable = cxl_pmem_security_disable, + .freeze = cxl_pmem_security_freeze, }; const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; From patchwork Fri Jul 15 21:09:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919727 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF59A5381 for ; Fri, 15 Jul 2022 21:09:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919384; x=1689455384; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tCo2bI3por77I/FcOdYtTCzcMFkh1j20dfEew9P9Xns=; b=LHhHebIpjJh9qGRRz69Uqt3rCiClBfbZ8cFd+2A0w9JoI6euHWYF4meB zfOTG+KooKv+dC35es4OJfWZJKLO/uBnDqg0tWNgNxbJEyo3k11ThtUck BuW5DUFIq2DO3hhpDX311Iiw+uAUgltBEtMENdYemNeJq4fHYE42wvADt OOHY+wL/u0YLilSdsKlj/FUk23Pvc14eLHqey3J04CJ4JAfVyaMlSa0K5 1aXd6sXX7xw+589ip6kjgInmeLvkxUkvjPGrC0lLtYybJy+ymuFRFhMzT YOAmfQ6BqwoWiDWLDkaWJCQ7at0Y8o7w8CXwn/OWPoMVLA7mctxQBj9mn Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="283458428" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="283458428" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:25 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="686104370" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by fmsmga003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:25 -0700 Subject: [PATCH RFC 09/15] tools/testing/cxl: Add "Freeze Security State" security opcode support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:24 -0700 Message-ID: <165791936487.2491387.4663628786437821239.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support to emulate a CXL mem device support the "Freeze Security State" operation. Signed-off-by: Dave Jiang --- tools/testing/cxl/test/mem.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 5f87a94d92ae..d8d08a89ec0c 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -312,6 +312,34 @@ static int mock_disable_passphrase(struct cxl_dev_state *cxlds, struct cxl_mbox_ return 0; } +static int mock_freeze_security(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) +{ + struct mock_mdev_data *mdata = dev_get_drvdata(cxlds->dev); + + if (cmd->size_in != 0) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (cmd->size_out != 0) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (mdata->security_state & CXL_PMEM_SEC_STATE_FROZEN) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (!(mdata->security_state & CXL_PMEM_SEC_STATE_USER_PASS_SET)) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + mdata->security_state |= CXL_PMEM_SEC_STATE_FROZEN; + return 0; +} + static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in; @@ -413,6 +441,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_DISABLE_PASSPHRASE: rc = mock_disable_passphrase(cxlds, cmd); break; + case CXL_MBOX_OP_FREEZE_SECURITY: + rc = mock_freeze_security(cxlds, cmd); + break; default: break; } From patchwork Fri Jul 15 21:09:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919725 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8E895381 for ; Fri, 15 Jul 2022 21:09:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919371; x=1689455371; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rtukhubC3aqh2vkOnHVty67vv9kxu5Rbgw6dYyDe7CQ=; b=eIG3uvN8l0WH8WslDGDZFdMsx4h3nOiCdJ2zkCCjOJP2tNIdlleP8WVT EqoMQ6LPxGWUBiTnAIH9N2g+CZzoZp5JBy9EYPNM+yrR4WFZAz+D7EVdq qotHyuxaly3/eyBdxbzNDTURNfqevE/QbCuZbThn60OPS4vlrwkv+noaz WOSDij0m6TPXOwO5VFgnkBoZmC4NxdjSo9zFmGlu64fa1WcDG5+9GgwWn ZntkSfgtXuzVNrcLVDBVSF/FNDzQ0+j7Z0TgIo3BIDgbPPpyRm+YXZutO GhHFptdIGitStwPF/I9O6Zw8PdEH/fuEHSq6D/zZAVLNarZLJc70Cc82V A==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="265689817" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="265689817" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:31 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="699348764" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:31 -0700 Subject: [PATCH RFC 10/15] x86: add an arch helper function to invalidate all cache for nvdimm From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:30 -0700 Message-ID: <165791937063.2491387.15277418618265930924.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The original implementation to flush all cache after unlocking the nvdimm resides in drivers/acpi/nfit/intel.c. This is a temporary stop gap until nvdimm with security operations arrives on other archs. With support CXL pmem supporting security operations, specifically "unlock" dimm, the need for an arch supported helper function to invalidate all CPU cache for nvdimm has arrived. Remove original implementation from acpi/nfit and add cross arch support for this operation. Add CONFIG_ARCH_HAS_NVDIMM_INVAL_CACHE Kconfig and allow x86_64 to opt in and provide the support via wbinvd_on_all_cpus() call. Signed-off-by: Dave Jiang Signed-off-by: Davidlohr Bueso --- arch/x86/Kconfig | 1 + arch/x86/mm/pat/set_memory.c | 8 ++++++++ drivers/acpi/nfit/intel.c | 28 +++++----------------------- include/linux/libnvdimm.h | 8 ++++++++ lib/Kconfig | 3 +++ 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index be0b95e51df6..8dbe89eba639 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -83,6 +83,7 @@ config X86 select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_PMEM_API if X86_64 + select ARCH_HAS_NVDIMM_INVAL_CACHE if X86_64 select ARCH_HAS_PTE_DEVMAP if X86_64 select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 1abd5438f126..e4cd1286deef 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -330,6 +330,14 @@ void arch_invalidate_pmem(void *addr, size_t size) EXPORT_SYMBOL_GPL(arch_invalidate_pmem); #endif +#ifdef CONFIG_ARCH_HAS_NVDIMM_INVAL_CACHE +void arch_invalidate_nvdimm_cache(void) +{ + wbinvd_on_all_cpus(); +} +EXPORT_SYMBOL_GPL(arch_invalidate_nvdimm_cache); +#endif + static void __cpa_flush_all(void *arg) { unsigned long cache = (unsigned long)arg; diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c index 8dd792a55730..242d2e9203e9 100644 --- a/drivers/acpi/nfit/intel.c +++ b/drivers/acpi/nfit/intel.c @@ -190,8 +190,6 @@ static int intel_security_change_key(struct nvdimm *nvdimm, } } -static void nvdimm_invalidate_cache(void); - static int __maybe_unused intel_security_unlock(struct nvdimm *nvdimm, const struct nvdimm_key_data *key_data) { @@ -228,7 +226,7 @@ static int __maybe_unused intel_security_unlock(struct nvdimm *nvdimm, } /* DIMM unlocked, invalidate all CPU caches before we read it */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); return 0; } @@ -298,7 +296,7 @@ static int __maybe_unused intel_security_erase(struct nvdimm *nvdimm, return -ENOTTY; /* flush all cache before we erase DIMM */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); memcpy(nd_cmd.cmd.passphrase, key->data, sizeof(nd_cmd.cmd.passphrase)); rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); @@ -318,7 +316,7 @@ static int __maybe_unused intel_security_erase(struct nvdimm *nvdimm, } /* DIMM erased, invalidate all CPU caches before we read it */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); return 0; } @@ -355,7 +353,7 @@ static int __maybe_unused intel_security_query_overwrite(struct nvdimm *nvdimm) } /* flush all cache before we make the nvdimms available */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); return 0; } @@ -381,7 +379,7 @@ static int __maybe_unused intel_security_overwrite(struct nvdimm *nvdimm, return -ENOTTY; /* flush all cache before we erase DIMM */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); memcpy(nd_cmd.cmd.passphrase, nkey->data, sizeof(nd_cmd.cmd.passphrase)); rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); @@ -401,22 +399,6 @@ static int __maybe_unused intel_security_overwrite(struct nvdimm *nvdimm, } } -/* - * TODO: define a cross arch wbinvd equivalent when/if - * NVDIMM_FAMILY_INTEL command support arrives on another arch. - */ -#ifdef CONFIG_X86 -static void nvdimm_invalidate_cache(void) -{ - wbinvd_on_all_cpus(); -} -#else -static void nvdimm_invalidate_cache(void) -{ - WARN_ON_ONCE("cache invalidation required after unlock\n"); -} -#endif - static const struct nvdimm_security_ops __intel_security_ops = { .get_flags = intel_security_flags, .freeze = intel_security_freeze, diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 0d61e07b6827..455d54ec3c86 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -308,4 +308,12 @@ static inline void arch_invalidate_pmem(void *addr, size_t size) } #endif +#ifdef CONFIG_ARCH_HAS_NVDIMM_INVAL_CACHE +void arch_invalidate_nvdimm_cache(void); +#else +static inline void arch_invalidate_nvdimm_cache(void) +{ +} +#endif + #endif /* __LIBNVDIMM_H__ */ diff --git a/lib/Kconfig b/lib/Kconfig index eaaad4d85bf2..d4bc48eea635 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -652,6 +652,9 @@ config ARCH_NO_SG_CHAIN config ARCH_HAS_PMEM_API bool +config ARCH_HAS_NVDIMM_INVAL_CACHE + bool + config MEMREGION bool From patchwork Fri Jul 15 21:09:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919726 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 669955381 for ; Fri, 15 Jul 2022 21:09:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919377; x=1689455377; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SiRuRk9Q3gpxaUHCA0EXScnQYKNtaFE65XGq4hLyZY4=; b=P60vhFpGoLDgGwDhinkmDFpBhN/DofEwQN+RK0GEb8AEne8I13wPIRHU zzonMHGfB6FgIQ56/Owaiifsz3hoJ8aKUQTIArGStOXTE+OY2jQwsgcMV 9KTlyhXQNV7KdD1DxuQrUpkrmxQeSQMKnZXYZO6meUFXPVpg+R33VeNAd uiQ8vAG0nBR2Y5M71hGbIkuwoql/wTWmFxZEJxBYxTgS+DCvIwErohXZo nP/wrqhwoNzyXffnD65OkPBw+pdbKFYDX5Nmr9sPVWz5f1KoJF3hJKGrG xVSVwhoUfwz/HgNXhz1cOuB3eONV4ATOKT4+OVoS7OxNDwWLXp5LwPFDk Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="311568629" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="311568629" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:36 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="699348781" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:36 -0700 Subject: [PATCH RFC 11/15] cxl/pmem: Add "Unlock" security command support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:36 -0700 Message-ID: <165791937639.2491387.6281906434880014077.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Create callback function to support the nvdimm_security_ops() ->unlock() callback. Translate the operation to send "Unlock" security command for CXL mem device. When the mem device is unlocked, arch_invalidate_nvdimm_cache() is called in order to invalidate all CPU caches before attempting to access the mem device. See CXL 2.0 spec section 8.2.9.5.6.4 for reference. Signed-off-by: Dave Jiang --- drivers/cxl/cxlmem.h | 1 + drivers/cxl/security.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index ced85be291f3..ae8ccd484491 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -253,6 +253,7 @@ enum cxl_opcode { CXL_MBOX_OP_GET_SECURITY_STATE = 0x4500, CXL_MBOX_OP_SET_PASSPHRASE = 0x4501, CXL_MBOX_OP_DISABLE_PASSPHRASE = 0x4502, + CXL_MBOX_OP_UNLOCK = 0x4503, CXL_MBOX_OP_FREEZE_SECURITY = 0x4504, CXL_MBOX_OP_MAX = 0x10000 }; diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c index 6399266a5908..d15520f280f0 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -114,11 +114,32 @@ static int cxl_pmem_security_freeze(struct nvdimm *nvdimm) return cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_FREEZE_SECURITY, NULL, 0, NULL, 0); } +static int cxl_pmem_security_unlock(struct nvdimm *nvdimm, + const struct nvdimm_key_data *key_data) +{ + struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); + struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; + struct cxl_dev_state *cxlds = cxlmd->cxlds; + u8 pass[NVDIMM_PASSPHRASE_LEN]; + int rc; + + memcpy(pass, key_data->data, NVDIMM_PASSPHRASE_LEN); + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_UNLOCK, + pass, NVDIMM_PASSPHRASE_LEN, NULL, 0); + if (rc < 0) + return rc; + + /* DIMM unlocked, invalidate all CPU caches before we read it */ + arch_invalidate_nvdimm_cache(); + return 0; +} + static const struct nvdimm_security_ops __cxl_security_ops = { .get_flags = cxl_pmem_get_security_flags, .change_key = cxl_pmem_security_change_key, .disable = cxl_pmem_security_disable, .freeze = cxl_pmem_security_freeze, + .unlock = cxl_pmem_security_unlock, }; const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; From patchwork Fri Jul 15 21:09:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919728 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 50AC75381 for ; Fri, 15 Jul 2022 21:09:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919389; x=1689455389; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ALbb4cXTY9+mqVlkMTirRejxV8Px6TRXuQbpHZxnCkw=; b=in9UhsvQp1SQUA1d9Kfjc0imOff040ZlnfWd03VS+VvxZVTmtoMEkGs2 xmZ1Gg6BCVGbHkshdcZeOxHZHQ8VXJMrpfmvChk/LbAj0Dx+KJ7us+mkf TI4ZdrPNNvUsnrkymgqz/teV3P9AqFll7gv+qMxIN9BYfOrcd1YtXiKsy fQxhWjurGZO2ajA/I9h2luUPlxUaDHQStVr4CLSekc8fQf8sf7tEB0yqZ SKnRYLusNT0FmdaZeO6bL4rELf8pSaQnB01RIRfT3yFQhEtE5RsXKNLgg NZckSdogfndj7E+k0x/EHx/tIpBQamhErOZyG+NdTdVR8owj9XwaHhJ59 g==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="372215221" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="372215221" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:43 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="546797763" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:42 -0700 Subject: [PATCH RFC 12/15] tools/testing/cxl: Add "Unlock" security opcode support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:42 -0700 Message-ID: <165791938203.2491387.12136394174353676616.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support to emulate a CXL mem device support the "Unlock" operation. Signed-off-by: Dave Jiang --- tools/testing/cxl/test/mem.c | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index d8d08a89ec0c..55a83896ccb8 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -340,6 +340,52 @@ static int mock_freeze_security(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd return 0; } +static int mock_unlock_security(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) +{ + struct mock_mdev_data *mdata = dev_get_drvdata(cxlds->dev); + + if (cmd->size_in != NVDIMM_PASSPHRASE_LEN) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (cmd->size_out != 0) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (mdata->security_state & CXL_PMEM_SEC_STATE_FROZEN) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (!(mdata->security_state & CXL_PMEM_SEC_STATE_USER_PASS_SET)) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (mdata->security_state & CXL_PMEM_SEC_STATE_USER_PLIMIT) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (!(mdata->security_state & CXL_PMEM_SEC_STATE_LOCKED)) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (memcmp(cmd->payload_in, mdata->user_pass, NVDIMM_PASSPHRASE_LEN)) { + if (++mdata->user_limit == PASS_TRY_LIMIT) + mdata->security_state |= CXL_PMEM_SEC_STATE_USER_PLIMIT; + cmd->return_code = CXL_MBOX_CMD_RC_PASSPHRASE; + return -ENXIO; + } + + mdata->user_limit = 0; + mdata->security_state &= ~CXL_PMEM_SEC_STATE_LOCKED; + return 0; +} + static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in; @@ -444,6 +490,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_FREEZE_SECURITY: rc = mock_freeze_security(cxlds, cmd); break; + case CXL_MBOX_OP_UNLOCK: + rc = mock_unlock_security(cxlds, cmd); + break; default: break; } From patchwork Fri Jul 15 21:09:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919729 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A35275382 for ; Fri, 15 Jul 2022 21:09:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919389; x=1689455389; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=L/mYFlodFVBIt1ciLDhpJOinYXzfR4o+44dbw4W6rrc=; b=f5fr/gASPSlanICpGdCnok/xWksETT9YMaZkmYKQ/VI6iJOfmT+4/IsO AX7P5UyaQqiN3iayRoalPqczT+k1hpKp1iMWFNtyO8ilGCpu9uUTbfn8b EKivPJ/Sh24mkVnb8l5ytP6gOBWHY0dpbdOJLuSyxVPZ9VCuH8YshNZbL WcqhNIT8by2O/nuNXYs+bBF9se/GoeWyLYrGpzA39gDaSsSNVSsBfL8Ah 656Av9yMuIvkGyA6crlus7ofaSK2F1Yr/oYeb/PD7aCG+goxGLYefB9c6 eyy2hGSz0mQL9nxMbYd/DpCFY9pL0yPcwFWaztGQmwhN1auWYpY3sSni8 w==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="268921590" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="268921590" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:49 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="571680911" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:48 -0700 Subject: [PATCH RFC 13/15] cxl/pmem: Add "Passphrase Secure Erase" security command support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:48 -0700 Message-ID: <165791938847.2491387.8701829648751368015.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Create callback function to support the nvdimm_security_ops() ->erase() callback. Translate the operation to send "Passphrase Secure Erase" security command for CXL memory device. When the mem device is secure erased, arch_invalidate_nvdimm_cache() is called in order to invalidate all CPU caches before attempting to access the mem device again. See CXL 2.0 spec section 8.2.9.5.6.6 for reference. Signed-off-by: Dave Jiang Signed-off-by: Davidlohr Bueso --- drivers/cxl/cxlmem.h | 8 ++++++++ drivers/cxl/security.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index ae8ccd484491..4bcb02f625b4 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -255,6 +255,7 @@ enum cxl_opcode { CXL_MBOX_OP_DISABLE_PASSPHRASE = 0x4502, CXL_MBOX_OP_UNLOCK = 0x4503, CXL_MBOX_OP_FREEZE_SECURITY = 0x4504, + CXL_MBOX_OP_PASSPHRASE_ERASE = 0x4505, CXL_MBOX_OP_MAX = 0x10000 }; @@ -369,6 +370,13 @@ struct cxl_disable_pass { u8 pass[NVDIMM_PASSPHRASE_LEN]; } __packed; +/* passphrase erase payload */ +struct cxl_pass_erase { + u8 type; + u8 reserved[31]; + u8 pass[NVDIMM_PASSPHRASE_LEN]; +} __packed; + enum { CXL_PMEM_SEC_PASS_MASTER = 0, CXL_PMEM_SEC_PASS_USER, diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c index d15520f280f0..4add7f62e758 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -134,12 +134,41 @@ static int cxl_pmem_security_unlock(struct nvdimm *nvdimm, return 0; } +static int cxl_pmem_security_passphrase_erase(struct nvdimm *nvdimm, + const struct nvdimm_key_data *key, + 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_pass_erase *erase; + int rc; + + erase = kzalloc(sizeof(*erase), GFP_KERNEL); + if (!erase) + return -ENOMEM; + + erase->type = ptype == NVDIMM_MASTER ? + CXL_PMEM_SEC_PASS_MASTER : CXL_PMEM_SEC_PASS_USER; + memcpy(erase->pass, key->data, NVDIMM_PASSPHRASE_LEN); + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_PASSPHRASE_ERASE, + erase, sizeof(*erase), NULL, 0); + kfree(erase); + if (rc < 0) + return rc; + + /* DIMM erased, invalidate all CPU caches before we read it */ + arch_invalidate_nvdimm_cache(); + return 0; +} + static const struct nvdimm_security_ops __cxl_security_ops = { .get_flags = cxl_pmem_get_security_flags, .change_key = cxl_pmem_security_change_key, .disable = cxl_pmem_security_disable, .freeze = cxl_pmem_security_freeze, .unlock = cxl_pmem_security_unlock, + .erase = cxl_pmem_security_passphrase_erase, }; const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; From patchwork Fri Jul 15 21:09:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919730 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B5625382 for ; Fri, 15 Jul 2022 21:09:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919397; x=1689455397; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Rt4NRzraM8H7oR+YcFFuexpJF7C1WRDOymTTRbaTF3A=; b=WKAyQvVIFJ5QxG2DA3g3XFP50Yd7y3Af/OCVDeoKS76y1/FA+EHgoyjO y9mTrtUB5D1Drqts/QU9R9rFsyhV54Cg/OWRVdP8ssMWyudmCVgRJC/G5 bVW67mozpCqdd6vZFvxpQ/1N5MiHO/1zAhOqDX1wn67GRh5QSfl9YwCOp jnnR8l3rxGpLuHn3VuAZ47T6f8tJZqycA3a+sfsz/uirdHdzjy5SsVPcJ Ye+TOYHAr3mojRmD9h1nPhcq38aVWYPXysl5DYUA0q1bLbtkNPwU+mU4g 3cjtAu9lz4r52R0AxAYNex+J1FMzE8IrskzYM3TTotUeLM2imFWHAEEdX w==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="372215254" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="372215254" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:56 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="738805189" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:54 -0700 Subject: [PATCH RFC 14/15] tools/testing/cxl: Add "passphrase secure erase" opcode support From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:54 -0700 Message-ID: <165791939444.2491387.15869736767745094334.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support to emulate a CXL mem device support the "passphrase secure erase" operation. Signed-off-by: Dave Jiang --- tools/testing/cxl/test/mem.c | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 55a83896ccb8..ebc5e8768019 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -386,6 +386,62 @@ static int mock_unlock_security(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd return 0; } +static int mock_passphrase_erase(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) +{ + struct mock_mdev_data *mdata = dev_get_drvdata(cxlds->dev); + struct cxl_pass_erase *erase; + + if (cmd->size_in != sizeof(*erase)) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (cmd->size_out != 0) { + cmd->return_code = CXL_MBOX_CMD_RC_INPUT; + return -EINVAL; + } + + if (mdata->security_state & CXL_PMEM_SEC_STATE_FROZEN) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (mdata->security_state & CXL_PMEM_SEC_STATE_USER_PLIMIT) { + cmd->return_code = CXL_MBOX_CMD_RC_SECURITY; + return -ENXIO; + } + + if (erase->type == CXL_PMEM_SEC_PASS_MASTER && + mdata->security_state & CXL_PMEM_SEC_STATE_MASTER_PASS_SET && + memcmp(mdata->master_pass, erase->pass, NVDIMM_PASSPHRASE_LEN)) { + if (++mdata->master_limit == PASS_TRY_LIMIT) + mdata->security_state |= CXL_PMEM_SEC_STATE_MASTER_PLIMIT; + cmd->return_code = CXL_MBOX_CMD_RC_PASSPHRASE; + return -ENXIO; + } + + if (erase->type == CXL_PMEM_SEC_PASS_USER && + mdata->security_state & CXL_PMEM_SEC_STATE_USER_PASS_SET && + memcmp(mdata->user_pass, erase->pass, NVDIMM_PASSPHRASE_LEN)) { + if (++mdata->user_limit == PASS_TRY_LIMIT) + mdata->security_state |= CXL_PMEM_SEC_STATE_USER_PLIMIT; + cmd->return_code = CXL_MBOX_CMD_RC_PASSPHRASE; + return -ENXIO; + } + + if (erase->type == CXL_PMEM_SEC_PASS_USER) { + mdata->security_state &= ~CXL_PMEM_SEC_STATE_USER_PASS_SET; + mdata->user_limit = 0; + memset(mdata->user_pass, 0, NVDIMM_PASSPHRASE_LEN); + } else if (erase->type == CXL_PMEM_SEC_PASS_MASTER) { + mdata->master_limit = 0; + } + + mdata->security_state &= ~CXL_PMEM_SEC_STATE_LOCKED; + + return 0; +} + static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in; @@ -493,6 +549,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_UNLOCK: rc = mock_unlock_security(cxlds, cmd); break; + case CXL_MBOX_OP_PASSPHRASE_ERASE: + rc = mock_passphrase_erase(cxlds, cmd); + break; default: break; } From patchwork Fri Jul 15 21:10:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919731 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9ECDE5381 for ; Fri, 15 Jul 2022 21:10:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919401; x=1689455401; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gFdu+GYkijOGsJbm6XpIIfeJDUF+PDzXjZkXHW/IJDE=; b=Ld/UOP2dRT68iCYuqQLqoeRZzfc3IXGnJHiSHp3Da/fSTp48rUGpzRjr XBftNwqwJP5IyjbTG288M0MXrbxvHvYMdIG44TrgrzA3UlbMVcXJBOdua ba+zxxgwFEhwEpwhQAEe6od82rOzDw/8RU2riWKJ625ISFiITSZHMc8Iu vlsJ2s8yLRlMei7Rbds3mrqYUx0XRASgxQEXCig9EARP0sRPduNady9Sj NJq/icrSc/u/iHZN479pJsn6kBFQ9Pn6cKPL3CWMNFUa7GsOqQir3DQV7 QRymMnbXFBY0aiRbyvaiGlO6NbBSfPiQlOOOYAdKLGBK8sNpsgTR0xR8M g==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="286636720" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="286636720" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:10:01 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="624010662" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:10:00 -0700 Subject: [PATCH RFC 15/15] nvdimm/cxl/pmem: Add support for master passphrase disable security command From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:10:00 -0700 Message-ID: <165791940024.2491387.14002847822890520271.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 Precedence: bulk X-Mailing-List: nvdimm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The original nvdimm_security_ops ->disable() only supports user passphrase for security disable. The CXL spec introduced the disabling of master passphrase. Add a ->disable_master() callback to support this new operation and leaving the old ->disable() mechanism alone. A "disable_master" command is added for the sysfs attribute in order to allow command to be issued from userspace. ndctl will need enabling in order to utilize this new operation. Signed-off-by: Dave Jiang --- drivers/cxl/security.c | 28 ++++++++++++++++++---------- drivers/nvdimm/security.c | 33 ++++++++++++++++++++++++++------- include/linux/libnvdimm.h | 2 ++ 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c index 4add7f62e758..3dc04b50afaf 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -76,8 +76,9 @@ static int cxl_pmem_security_change_key(struct nvdimm *nvdimm, return rc; } -static int cxl_pmem_security_disable(struct nvdimm *nvdimm, - const struct nvdimm_key_data *key_data) +static int __cxl_pmem_security_disable(struct nvdimm *nvdimm, + const struct nvdimm_key_data *key_data, + enum nvdimm_passphrase_type ptype) { struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; @@ -89,14 +90,8 @@ static int cxl_pmem_security_disable(struct nvdimm *nvdimm, if (!dis_pass) return -ENOMEM; - /* - * While the CXL spec defines the ability to erase the master passphrase, - * the original nvdimm security ops does not provide that capability. - * In order to preserve backward compatibility, this callback will - * only support disable of user passphrase. The disable master passphrase - * ability will need to be added as a new callback. - */ - dis_pass->type = CXL_PMEM_SEC_PASS_USER; + dis_pass->type = ptype == NVDIMM_MASTER ? + CXL_PMEM_SEC_PASS_MASTER : CXL_PMEM_SEC_PASS_USER; memcpy(dis_pass->pass, key_data->data, NVDIMM_PASSPHRASE_LEN); rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_DISABLE_PASSPHRASE, @@ -105,6 +100,18 @@ static int cxl_pmem_security_disable(struct nvdimm *nvdimm, return rc; } +static int cxl_pmem_security_disable(struct nvdimm *nvdimm, + const struct nvdimm_key_data *key_data) +{ + return __cxl_pmem_security_disable(nvdimm, key_data, NVDIMM_USER); +} + +static int cxl_pmem_security_disable_master(struct nvdimm *nvdimm, + const struct nvdimm_key_data *key_data) +{ + return __cxl_pmem_security_disable(nvdimm, key_data, NVDIMM_MASTER); +} + static int cxl_pmem_security_freeze(struct nvdimm *nvdimm) { struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); @@ -169,6 +176,7 @@ static const struct nvdimm_security_ops __cxl_security_ops = { .freeze = cxl_pmem_security_freeze, .unlock = cxl_pmem_security_unlock, .erase = cxl_pmem_security_passphrase_erase, + .disable = cxl_pmem_security_disable_master, }; const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c index b5aa55c61461..c1c9d0feae9d 100644 --- a/drivers/nvdimm/security.c +++ b/drivers/nvdimm/security.c @@ -239,7 +239,8 @@ static int check_security_state(struct nvdimm *nvdimm) return 0; } -static int security_disable(struct nvdimm *nvdimm, unsigned int keyid) +static int security_disable(struct nvdimm *nvdimm, unsigned int keyid, + enum nvdimm_passphrase_type pass_type) { struct device *dev = &nvdimm->dev; struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); @@ -250,8 +251,13 @@ static int security_disable(struct nvdimm *nvdimm, unsigned int keyid) /* The bus lock should be held at the top level of the call stack */ lockdep_assert_held(&nvdimm_bus->reconfig_mutex); - if (!nvdimm->sec.ops || !nvdimm->sec.ops->disable - || !nvdimm->sec.flags) + if (!nvdimm->sec.ops || !nvdimm->sec.flags) + return -EOPNOTSUPP; + + if (pass_type == NVDIMM_USER && !nvdimm->sec.ops->disable) + return -EOPNOTSUPP; + + if (pass_type == NVDIMM_MASTER && !nvdimm->sec.ops->disable_master) return -EOPNOTSUPP; rc = check_security_state(nvdimm); @@ -263,12 +269,21 @@ static int security_disable(struct nvdimm *nvdimm, unsigned int keyid) if (!data) return -ENOKEY; - rc = nvdimm->sec.ops->disable(nvdimm, data); - dev_dbg(dev, "key: %d disable: %s\n", key_serial(key), + if (pass_type == NVDIMM_MASTER) { + rc = nvdimm->sec.ops->disable_master(nvdimm, data); + dev_dbg(dev, "key: %d disable_master: %s\n", key_serial(key), rc == 0 ? "success" : "fail"); + } else { + rc = nvdimm->sec.ops->disable(nvdimm, data); + dev_dbg(dev, "key: %d disable: %s\n", key_serial(key), + rc == 0 ? "success" : "fail"); + } nvdimm_put_key(key); - nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); + if (pass_type == NVDIMM_MASTER) + nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER); + else + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); return rc; } @@ -473,6 +488,7 @@ void nvdimm_security_overwrite_query(struct work_struct *work) #define OPS \ C( OP_FREEZE, "freeze", 1), \ C( OP_DISABLE, "disable", 2), \ + C( OP_DISABLE_MASTER, "disable_master", 2), \ C( OP_UPDATE, "update", 3), \ C( OP_ERASE, "erase", 2), \ C( OP_OVERWRITE, "overwrite", 2), \ @@ -524,7 +540,10 @@ ssize_t nvdimm_security_store(struct device *dev, const char *buf, size_t len) rc = nvdimm_security_freeze(nvdimm); } else if (i == OP_DISABLE) { dev_dbg(dev, "disable %u\n", key); - rc = security_disable(nvdimm, key); + rc = security_disable(nvdimm, key, NVDIMM_USER); + } else if (i == OP_DISABLE_MASTER) { + dev_dbg(dev, "disable_master %u\n", key); + rc = security_disable(nvdimm, key, NVDIMM_MASTER); } else if (i == OP_UPDATE || i == OP_MASTER_UPDATE) { dev_dbg(dev, "%s %u %u\n", ops[i].name, key, newkey); rc = security_update(nvdimm, key, newkey, i == OP_UPDATE diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 455d54ec3c86..07e4e7572089 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -179,6 +179,8 @@ struct nvdimm_security_ops { int (*overwrite)(struct nvdimm *nvdimm, const struct nvdimm_key_data *key_data); int (*query_overwrite)(struct nvdimm *nvdimm); + int (*disable_master)(struct nvdimm *nvdimm, + const struct nvdimm_key_data *key_data); }; enum nvdimm_fwa_state {