From patchwork Fri Sep 28 22:44:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10620493 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F4611750 for ; Fri, 28 Sep 2018 22:44:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8DE332BE78 for ; Fri, 28 Sep 2018 22:44:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 80A212BE81; Fri, 28 Sep 2018 22:44:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0EBC22BE78 for ; Fri, 28 Sep 2018 22:44:52 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 02E072115C08D; Fri, 28 Sep 2018 15:44:52 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.115; helo=mga14.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org 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 ml01.01.org (Postfix) with ESMTPS id A775121106FA6 for ; Fri, 28 Sep 2018 15:44:50 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Sep 2018 15:44:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,316,1534834800"; d="scan'208";a="87653942" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by orsmga003.jf.intel.com with ESMTP; 28 Sep 2018 15:44:49 -0700 Subject: [PATCH v2 1/5] libnvdimm: introduce NDD_SECURITY_BUSY flag From: Dave Jiang To: dan.j.williams@intel.com Date: Fri, 28 Sep 2018 15:44:49 -0700 Message-ID: <153817468975.19407.13097333227524016079.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> References: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Adding a flag for nvdimm->flags to support erase functions. While it's ok to hold the nvdimm_bus lock for secure erase due to minimal time to execute the command, overwrite requires a significantly longer time and makes this impossible. The flag will block any drivers from being loaded and DIMMs being probed. Signed-off-by: Dave Jiang --- drivers/nvdimm/dimm.c | 4 +++ drivers/nvdimm/dimm_devs.c | 52 +++++++++++++++++++++++++++++++++++++++++- drivers/nvdimm/nd.h | 3 ++ drivers/nvdimm/region_devs.c | 7 ++++++ include/linux/libnvdimm.h | 2 ++ 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c index b6381ddbd6c1..5ff9367b8671 100644 --- a/drivers/nvdimm/dimm.c +++ b/drivers/nvdimm/dimm.c @@ -26,6 +26,10 @@ static int nvdimm_probe(struct device *dev) struct nvdimm_drvdata *ndd; int rc; + rc = nvdimm_check_security_busy(dev); + if (rc) + return rc; + rc = nvdimm_check_config_data(dev); if (rc) { /* not required for non-aliased nvdimm, ex. NVDIMM-N */ diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 656a8fafca8e..7a71ea666676 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -187,12 +187,16 @@ static int nvdimm_security_erase(struct device *dev, unsigned int keyid) struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); struct key *key; struct user_key_payload *payload; - int rc = 0; + int rc; bool is_userkey = false; if (!nvdimm->security_ops) return -EOPNOTSUPP; + rc = nvdimm_check_security_busy(dev); + if (rc) + return rc; + nvdimm_bus_lock(&nvdimm_bus->dev); if (atomic_read(&nvdimm->busy)) { dev_warn(dev, "Unable to secure erase while DIMM active.\n"); @@ -212,6 +216,8 @@ static int nvdimm_security_erase(struct device *dev, unsigned int keyid) goto out; } + nvdimm_set_security_busy(dev); + /* look for a key from cached key if exists */ key = nvdimm_get_and_verify_key(dev, keyid); if (IS_ERR(key)) { @@ -246,6 +252,7 @@ static int nvdimm_security_erase(struct device *dev, unsigned int keyid) key_put(key); out: + nvdimm_clear_security_busy(dev); nvdimm_bus_unlock(&nvdimm_bus->dev); nvdimm_security_get_state(dev); return rc; @@ -262,6 +269,10 @@ static int nvdimm_security_freeze_lock(struct device *dev) if (nvdimm->state == NVDIMM_SECURITY_UNSUPPORTED) return -EOPNOTSUPP; + rc = nvdimm_check_security_busy(dev); + if (rc) + return rc; + rc = nvdimm->security_ops->freeze_lock(nvdimm); if (rc < 0) return rc; @@ -284,6 +295,10 @@ static int nvdimm_security_disable(struct device *dev, unsigned int keyid) if (nvdimm->state == NVDIMM_SECURITY_UNSUPPORTED) return -EOPNOTSUPP; + rc = nvdimm_check_security_busy(dev); + if (rc) + return rc; + /* look for a key from cached key */ key = nvdimm_get_and_verify_key(dev, keyid); if (IS_ERR(key)) @@ -335,6 +350,10 @@ int nvdimm_security_unlock_dimm(struct device *dev) nvdimm->state == NVDIMM_SECURITY_DISABLED) return 0; + rc = nvdimm_check_security_busy(dev); + if (rc) + return rc; + key = nvdimm_get_key(dev); if (!key) key = nvdimm_request_key(dev); @@ -390,6 +409,10 @@ static int nvdimm_security_change_key(struct device *dev, if (nvdimm->state == NVDIMM_SECURITY_FROZEN) return -EBUSY; + rc = nvdimm_check_security_busy(dev); + if (rc) + return rc; + /* look for a key from cached key if exists */ old_key = nvdimm_get_and_verify_key(dev, old_keyid); if (IS_ERR(old_key)) @@ -467,6 +490,33 @@ static int nvdimm_security_change_key(struct device *dev, return rc; } +/* + * Check if we are doing security wipes + */ +int nvdimm_check_security_busy(struct device *dev) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + + if (test_bit(NDD_SECURITY_BUSY, &nvdimm->flags)) + return -EBUSY; + + return 0; +} + +void nvdimm_set_security_busy(struct device *dev) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + + set_bit(NDD_SECURITY_BUSY, &nvdimm->flags); +} + +void nvdimm_clear_security_busy(struct device *dev) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + + clear_bit(NDD_SECURITY_BUSY, &nvdimm->flags); +} + /* * Retrieve bus and dimm handle and return if this bus supports * get_config_data commands diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index fa3b89127078..252fbe6d4ecd 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -239,6 +239,9 @@ void nd_region_exit(void); struct nvdimm; struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping); int nvdimm_check_config_data(struct device *dev); +int nvdimm_check_security_busy(struct device *dev); +void nvdimm_set_security_busy(struct device *dev); +void nvdimm_clear_security_busy(struct device *dev); int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd); int nvdimm_init_config_data(struct nvdimm_drvdata *ndd); int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset, diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index fa37afcd43ff..3e089c533397 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -78,6 +78,13 @@ int nd_region_activate(struct nd_region *nd_region) for (i = 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping = &nd_region->mapping[i]; struct nvdimm *nvdimm = nd_mapping->nvdimm; + int rc; + + rc = nvdimm_check_security_busy(&nvdimm->dev); + if (rc) { + nvdimm_bus_unlock(&nd_region->dev); + return rc; + } /* at least one null hint slot per-dimm for the "no-hint" case */ flush_data_size += sizeof(void *); diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index c352b8195675..32c1da8c49e2 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -38,6 +38,8 @@ enum { NDD_UNARMED = 1, /* locked memory devices should not be accessed */ NDD_LOCKED = 2, + /* memory under security wipes should not be accessed */ + NDD_SECURITY_BUSY = 3, /* need to set a limit somewhere, but yes, this is likely overkill */ ND_IOCTL_MAX_BUFLEN = SZ_4M, From patchwork Fri Sep 28 22:44:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10620501 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 80984913 for ; Fri, 28 Sep 2018 22:45:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6ED402BE78 for ; Fri, 28 Sep 2018 22:45:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 628D42BE81; Fri, 28 Sep 2018 22:45:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A50212BE78 for ; Fri, 28 Sep 2018 22:45:21 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 6E3DF2115C094; Fri, 28 Sep 2018 15:45:21 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.93; helo=mga11.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org 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 ml01.01.org (Postfix) with ESMTPS id B7FF02115C092 for ; Fri, 28 Sep 2018 15:45:20 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Sep 2018 15:45:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,316,1534834800"; d="scan'208";a="261338057" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by orsmga005.jf.intel.com with ESMTP; 28 Sep 2018 15:44:55 -0700 Subject: [PATCH v2 2/5] libnvdimm: Add security DSM overwrite support From: Dave Jiang To: dan.j.williams@intel.com Date: Fri, 28 Sep 2018 15:44:55 -0700 Message-ID: <153817469524.19407.4267332786097495660.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> References: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP We are adding support for the security calls of ovewrite and query overwrite from Intel DSM spec v1.7. This will allow triggering of overwrite on Intel NVDIMMs. The overwrite operation can take tens of minutes. When the overwrite DSM is issued successfully, the NVDIMMs will be unaccessible. The kernel will do backoff polling to detect when the overwrite process is completed. According to the DSM spec v1.7, the 128G NVDIMMs can take up to 15mins to perform overwrite and larger DIMMs will take longer. Signed-off-by: Dave Jiang --- drivers/acpi/nfit/intel.c | 113 ++++++++++++++++++++++++++++++++++++ drivers/acpi/nfit/intel.h | 3 + drivers/acpi/nfit/nfit.h | 1 drivers/nvdimm/core.c | 3 + drivers/nvdimm/dimm_devs.c | 140 ++++++++++++++++++++++++++++++++++++++++++++ drivers/nvdimm/nd-core.h | 3 + include/linux/libnvdimm.h | 4 + 7 files changed, 266 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c index 8d2413810a5f..2783e060e2b1 100644 --- a/drivers/acpi/nfit/intel.c +++ b/drivers/acpi/nfit/intel.c @@ -18,6 +18,112 @@ #include "intel.h" #include "nfit.h" +static int intel_dimm_security_query_overwrite(struct nvdimm *nvdimm) +{ + int cmd_rc, rc = 0; + struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); + struct { + struct nd_cmd_pkg pkg; + struct nd_intel_query_overwrite cmd; + } nd_cmd = { + .pkg = { + .nd_command = NVDIMM_INTEL_QUERY_OVERWRITE, + .nd_family = NVDIMM_FAMILY_INTEL, + .nd_size_in = 0, + .nd_size_out = ND_INTEL_STATUS_SIZE, + .nd_fw_size = ND_INTEL_STATUS_SIZE, + }, + .cmd = { + .status = 0, + }, + }; + + if (!test_bit(NVDIMM_INTEL_QUERY_OVERWRITE, &nfit_mem->dsm_mask)) + return -ENOTTY; + + rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), &cmd_rc); + if (rc < 0) + goto out; + if (cmd_rc < 0) { + rc = cmd_rc; + goto out; + } + + switch (nd_cmd.cmd.status) { + case 0: + break; + case ND_INTEL_STATUS_OQUERY_INPROGRESS: + rc = -EBUSY; + goto out; + default: + rc = -ENXIO; + goto out; + } + + /* flush all cache before we make the nvdimms available */ + wbinvd_on_all_cpus(); + nfit_mem->overwrite = false; + +out: + return rc; +} + +static int intel_dimm_security_overwrite(struct nvdimm *nvdimm, + const struct nvdimm_key_data *nkey) +{ + int cmd_rc, rc = 0; + struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); + struct { + struct nd_cmd_pkg pkg; + struct nd_intel_overwrite cmd; + } nd_cmd = { + .pkg = { + .nd_command = NVDIMM_INTEL_OVERWRITE, + .nd_family = NVDIMM_FAMILY_INTEL, + .nd_size_in = ND_INTEL_PASSPHRASE_SIZE, + .nd_size_out = ND_INTEL_STATUS_SIZE, + .nd_fw_size = ND_INTEL_STATUS_SIZE, + }, + .cmd = { + .status = 0, + }, + }; + + if (!test_bit(NVDIMM_INTEL_OVERWRITE, &nfit_mem->dsm_mask)) + return -ENOTTY; + + /* flush all cache before we erase DIMM */ + wbinvd_on_all_cpus(); + memcpy(nd_cmd.cmd.passphrase, nkey->data, + sizeof(nd_cmd.cmd.passphrase)); + rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), &cmd_rc); + if (rc < 0) + goto out; + if (cmd_rc < 0) { + rc = cmd_rc; + goto out; + } + + switch (nd_cmd.cmd.status) { + case 0: + nfit_mem->overwrite = true; + break; + case ND_INTEL_STATUS_OVERWRITE_UNSUPPORTED: + rc = -ENOTSUPP; + break; + case ND_INTEL_STATUS_INVALID_PASS: + rc = -EINVAL; + goto out; + case ND_INTEL_STATUS_INVALID_STATE: + default: + rc = -ENXIO; + goto out; + } + + out: + return rc; +} + static int intel_dimm_security_erase(struct nvdimm *nvdimm, const struct nvdimm_key_data *nkey) { @@ -317,6 +423,11 @@ static int intel_dimm_security_state(struct nvdimm *nvdimm, return 0; } + if (nfit_mem->overwrite == true) { + *state = NVDIMM_SECURITY_OVERWRITE; + return 0; + } + *state = NVDIMM_SECURITY_DISABLED; rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), &cmd_rc); if (rc < 0) @@ -365,5 +476,7 @@ static const struct nvdimm_security_ops __intel_security_ops = { .disable = intel_dimm_security_disable, .freeze_lock = intel_dimm_security_freeze_lock, .erase = intel_dimm_security_erase, + .overwrite = intel_dimm_security_overwrite, + .query_overwrite = intel_dimm_security_query_overwrite, }; const struct nvdimm_security_ops *intel_security_ops = &__intel_security_ops; diff --git a/drivers/acpi/nfit/intel.h b/drivers/acpi/nfit/intel.h index f831084f95fa..65d57a6abbc2 100644 --- a/drivers/acpi/nfit/intel.h +++ b/drivers/acpi/nfit/intel.h @@ -17,12 +17,15 @@ extern const struct nvdimm_security_ops *intel_security_ops; #define ND_INTEL_STATUS_NOT_READY 9 #define ND_INTEL_STATUS_INVALID_STATE 10 #define ND_INTEL_STATUS_INVALID_PASS 11 +#define ND_INTEL_STATUS_OVERWRITE_UNSUPPORTED 0x10007 +#define ND_INTEL_STATUS_OQUERY_INPROGRESS 0x10007 #define ND_INTEL_SEC_STATE_ENABLED 0x02 #define ND_INTEL_SEC_STATE_LOCKED 0x04 #define ND_INTEL_SEC_STATE_FROZEN 0x08 #define ND_INTEL_SEC_STATE_PLIMIT 0x10 #define ND_INTEL_SEC_STATE_UNSUPPORTED 0x20 +#define ND_INTEL_SEC_STATE_OVERWRITE 0x40 struct nd_intel_get_security_state { u32 status; diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h index 36c8695a3d27..e36a111d393a 100644 --- a/drivers/acpi/nfit/nfit.h +++ b/drivers/acpi/nfit/nfit.h @@ -198,6 +198,7 @@ struct nfit_mem { int family; bool has_lsr; bool has_lsw; + bool overwrite; char id[NFIT_DIMM_ID_LEN+1]; }; diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index acce050856a8..b2496c06178b 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -437,6 +437,9 @@ static __init int libnvdimm_init(void) { int rc; + rc = nvdimm_devs_init(); + if (rc) + return rc; rc = nvdimm_bus_init(); if (rc) return rc; diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 7a71ea666676..73f7e879d6e0 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -28,6 +28,7 @@ #include "nd.h" static DEFINE_IDA(dimm_ida); +static struct workqueue_struct *nvdimm_wq; /* * Find key that's cached with nvdimm @@ -181,6 +182,126 @@ int nvdimm_security_get_state(struct device *dev) return nvdimm->security_ops->state(nvdimm, &nvdimm->state); } +static void nvdimm_overwrite_query(struct work_struct *work) +{ + struct nvdimm *nvdimm; + struct nvdimm_bus *nvdimm_bus; + int rc; + unsigned int tmo; + + nvdimm = container_of(work, typeof(*nvdimm), dwork.work); + nvdimm_bus = walk_to_nvdimm_bus(&nvdimm->dev); + tmo = nvdimm->overwrite_tmo; + + if (!nvdimm->security_ops) + return; + + rc = nvdimm->security_ops->query_overwrite(nvdimm); + if (rc == -EBUSY) { + + /* setup delayed work again */ + tmo += 10; + queue_delayed_work(nvdimm_wq, &nvdimm->dwork, tmo * HZ); + nvdimm->overwrite_tmo = min(15U * 60U, tmo); + return; + } + + if (rc < 0) + dev_warn(&nvdimm->dev, "Overwrite failed\n"); + else + dev_info(&nvdimm->dev, "Overwrite completed\n"); + + nvdimm->overwrite_tmo = 0; + nvdimm_clear_security_busy(&nvdimm->dev); + nvdimm_security_get_state(&nvdimm->dev); +} + +static int nvdimm_security_overwrite(struct device *dev, unsigned int keyid) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); + struct key *key; + struct user_key_payload *payload; + int rc; + char pass[NVDIMM_PASSPHRASE_LEN]; + bool is_userkey = false; + + if (!nvdimm->security_ops) + return 0; + + rc = nvdimm_check_security_busy(dev); + if (rc) + return rc; + + nvdimm_bus_lock(&nvdimm_bus->dev); + if (atomic_read(&nvdimm->busy)) { + dev_warn(dev, "Unable to overwrite while DIMM active.\n"); + rc = -EBUSY; + goto out; + } + + if (dev_get_drvdata(dev)) { + dev_warn(dev, "Unable to overwrite while DIMM active.\n"); + rc = -EINVAL; + goto out; + } + + if (nvdimm->state == NVDIMM_SECURITY_UNSUPPORTED) { + dev_warn(dev, "Attempt to overwrite in wrong state.\n"); + rc = -EOPNOTSUPP; + goto out; + } + + /* look for a key from keyring if exists and remove */ + key = nvdimm_get_and_verify_key(dev, keyid); + if (IS_ERR(key)) { + dev_dbg(dev, "Unable to get and verify key\n"); + rc = PTR_ERR(key); + goto out; + } + if (!key) { + dev_dbg(dev, "No cached key found\n"); + /* get old user key */ + key = nvdimm_lookup_user_key(dev, keyid); + if (key) + is_userkey = true; + } + + if (key) { + down_read(&key->sem); + payload = key->payload.data[0]; + memcpy(pass, payload->data, NVDIMM_PASSPHRASE_LEN); + up_read(&key->sem); + } else + memset(pass, 0, NVDIMM_PASSPHRASE_LEN); + + nvdimm_set_security_busy(dev); + /* + * Overwrite can execute w/o passphrase. we will let the hardware + * determine whether we need a passphrase or not. + */ + rc = nvdimm->security_ops->overwrite(nvdimm, (void *)pass); + if (rc == 0) { + if (key) { + if (!is_userkey) { + key_invalidate(key); + nvdimm->key = NULL; + } + key_put(key); + memset(pass, 0, NVDIMM_PASSPHRASE_LEN); + } + nvdimm->state = NVDIMM_SECURITY_OVERWRITE; + queue_delayed_work(nvdimm_wq, &nvdimm->dwork, 0); + } else + nvdimm_clear_security_busy(dev); + + out: + nvdimm_bus_unlock(&nvdimm_bus->dev); + nvdimm_security_get_state(dev); + return rc; + +} + static int nvdimm_security_erase(struct device *dev, unsigned int keyid) { struct nvdimm *nvdimm = to_nvdimm(dev); @@ -898,6 +1019,8 @@ __weak ssize_t security_show(struct device *dev, return sprintf(buf, "locked\n"); case NVDIMM_SECURITY_FROZEN: return sprintf(buf, "frozen\n"); + case NVDIMM_SECURITY_OVERWRITE: + return sprintf(buf, "overwrite\n"); case NVDIMM_SECURITY_UNSUPPORTED: default: return sprintf(buf, "unsupported\n"); @@ -944,6 +1067,9 @@ static ssize_t security_store(struct device *dev, return -EINVAL; dev_dbg(dev, "erase %#x\n", old_key); rc = nvdimm_security_erase(dev, old_key); + } else if (sysfs_streq(cmd, "overwrite")) { + dev_dbg(dev, "overwrite %u\n", old_key); + rc = nvdimm_security_overwrite(dev, old_key); } else return -EINVAL; @@ -1000,6 +1126,8 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, dev->type = &nvdimm_device_type; dev->devt = MKDEV(nvdimm_major, nvdimm->id); dev->groups = groups; + nvdimm->overwrite_tmo = 0; + INIT_DELAYED_WORK(&nvdimm->dwork, nvdimm_overwrite_query); nd_device_register(dev); return nvdimm; @@ -1276,7 +1404,17 @@ int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count) } EXPORT_SYMBOL_GPL(nvdimm_bus_check_dimm_count); -void __exit nvdimm_devs_exit(void) +int __init nvdimm_devs_init(void) +{ + nvdimm_wq = create_singlethread_workqueue("nvdimm"); + if (!nvdimm_wq) + return -ENOMEM; + + return 0; +} + +void nvdimm_devs_exit(void) { + destroy_workqueue(nvdimm_wq); ida_destroy(&dimm_ida); } diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index b4a6ca15d077..efc7eb9e624c 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -46,6 +46,8 @@ struct nvdimm { const struct nvdimm_security_ops *security_ops; enum nvdimm_security_state state; struct key *key; + struct delayed_work dwork; + unsigned int overwrite_tmo; }; /** @@ -81,6 +83,7 @@ struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev); int __init nvdimm_bus_init(void); void nvdimm_bus_exit(void); void nvdimm_devs_exit(void); +int nvdimm_devs_init(void); void nd_region_devs_exit(void); void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev); struct nd_region; diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 32c1da8c49e2..b59ff6b798b2 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -163,6 +163,7 @@ enum nvdimm_security_state { NVDIMM_SECURITY_UNLOCKED, NVDIMM_SECURITY_LOCKED, NVDIMM_SECURITY_FROZEN, + NVDIMM_SECURITY_OVERWRITE, NVDIMM_SECURITY_UNSUPPORTED, }; @@ -186,6 +187,9 @@ struct nvdimm_security_ops { int (*freeze_lock)(struct nvdimm *nvdimm); int (*erase)(struct nvdimm *nvdimm, const struct nvdimm_key_data *nkey); + int (*overwrite)(struct nvdimm *nvdimm, + const struct nvdimm_key_data *nkey); + int (*query_overwrite)(struct nvdimm *nvdimm); }; void badrange_init(struct badrange *badrange); From patchwork Fri Sep 28 22:45:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10620495 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A1B01175A for ; Fri, 28 Sep 2018 22:45:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E5C92BE78 for ; Fri, 28 Sep 2018 22:45:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7FCE72BE81; Fri, 28 Sep 2018 22:45:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 26EB12BE78 for ; Fri, 28 Sep 2018 22:45:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 1F0D32115C087; Fri, 28 Sep 2018 15:45:03 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.115; helo=mga14.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org 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 ml01.01.org (Postfix) with ESMTPS id C34AD21106FA6 for ; Fri, 28 Sep 2018 15:45:01 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Sep 2018 15:45:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,316,1534834800"; d="scan'208";a="77267860" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by orsmga008.jf.intel.com with ESMTP; 28 Sep 2018 15:45:00 -0700 Subject: [PATCH v2 3/5] nfit_test: Add overwrite support for nfit_test From: Dave Jiang To: dan.j.williams@intel.com Date: Fri, 28 Sep 2018 15:45:00 -0700 Message-ID: <153817470075.19407.12696397727175523377.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> References: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP With the implementation of Intel NVDIMM DSM overwrite, we are adding unit test to nfit_test for testing of overwrite operation. Signed-off-by: Dave Jiang --- drivers/acpi/nfit/intel.h | 1 + tools/testing/nvdimm/test/nfit.c | 55 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/drivers/acpi/nfit/intel.h b/drivers/acpi/nfit/intel.h index 65d57a6abbc2..c7426ebf3d08 100644 --- a/drivers/acpi/nfit/intel.h +++ b/drivers/acpi/nfit/intel.h @@ -19,6 +19,7 @@ extern const struct nvdimm_security_ops *intel_security_ops; #define ND_INTEL_STATUS_INVALID_PASS 11 #define ND_INTEL_STATUS_OVERWRITE_UNSUPPORTED 0x10007 #define ND_INTEL_STATUS_OQUERY_INPROGRESS 0x10007 +#define ND_INTEL_STATUS_OQUERY_SEQUENCE_ERR 0x20007 #define ND_INTEL_SEC_STATE_ENABLED 0x02 #define ND_INTEL_SEC_STATE_LOCKED 0x04 diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 1d7ae7aecb46..ee09ea84823a 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -149,6 +149,7 @@ static int dimm_fail_cmd_code[NUM_DCR]; struct nfit_test_sec { u8 state; u8 passphrase[32]; + u64 overwrite_end_time; } dimm_sec_info[NUM_DCR]; static const struct nd_intel_smart smart_def = { @@ -1072,6 +1073,50 @@ static int nd_intel_test_cmd_secure_erase(struct nfit_test *t, return 0; } +static int nd_intel_test_cmd_overwrite(struct nfit_test *t, + struct nd_intel_overwrite *nd_cmd, + unsigned int buf_len, int dimm) +{ + struct device *dev = &t->pdev.dev; + struct nfit_test_sec *sec = &dimm_sec_info[dimm]; + + if ((sec->state & ND_INTEL_SEC_STATE_ENABLED) && + memcmp(nd_cmd->passphrase, sec->passphrase, + ND_INTEL_PASSPHRASE_SIZE) != 0) { + nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS; + dev_dbg(dev, "overwrite: wrong passphrase\n"); + return 0; + } + + memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); + sec->state = ND_INTEL_SEC_STATE_OVERWRITE; + dev_dbg(dev, "overwrite progressing.\n"); + sec->overwrite_end_time = get_jiffies_64() + 5 * HZ; + + return 0; +} + +static int nd_intel_test_cmd_query_overwrite(struct nfit_test *t, + struct nd_intel_query_overwrite *nd_cmd, + unsigned int buf_len, int dimm) +{ + struct device *dev = &t->pdev.dev; + struct nfit_test_sec *sec = &dimm_sec_info[dimm]; + + if (!(sec->state & ND_INTEL_SEC_STATE_OVERWRITE)) { + nd_cmd->status = ND_INTEL_STATUS_OQUERY_SEQUENCE_ERR; + return 0; + } + + if (time_is_before_jiffies64(sec->overwrite_end_time)) { + sec->overwrite_end_time = 0; + sec->state = 0; + dev_dbg(dev, "overwrite is complete\n"); + } else + nd_cmd->status = ND_INTEL_STATUS_OQUERY_INPROGRESS; + return 0; +} + static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func) { int i; @@ -1143,6 +1188,14 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc, rc = nd_intel_test_cmd_secure_erase(t, buf, buf_len, i); break; + case NVDIMM_INTEL_OVERWRITE: + rc = nd_intel_test_cmd_overwrite(t, + buf, buf_len, i - t->dcr_idx); + break; + case NVDIMM_INTEL_QUERY_OVERWRITE: + rc = nd_intel_test_cmd_query_overwrite(t, + buf, buf_len, i - t->dcr_idx); + break; case ND_INTEL_ENABLE_LSS_STATUS: rc = nd_intel_test_cmd_set_lss_status(t, buf, buf_len); @@ -2378,6 +2431,8 @@ static void nfit_test0_setup(struct nfit_test *t) set_bit(NVDIMM_INTEL_UNLOCK_UNIT, &acpi_desc->dimm_cmd_force_en); set_bit(NVDIMM_INTEL_FREEZE_LOCK, &acpi_desc->dimm_cmd_force_en); set_bit(NVDIMM_INTEL_SECURE_ERASE, &acpi_desc->dimm_cmd_force_en); + set_bit(NVDIMM_INTEL_OVERWRITE, &acpi_desc->dimm_cmd_force_en); + set_bit(NVDIMM_INTEL_QUERY_OVERWRITE, &acpi_desc->dimm_cmd_force_en); } static void nfit_test1_setup(struct nfit_test *t) From patchwork Fri Sep 28 22:45:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10620497 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ACBD41750 for ; Fri, 28 Sep 2018 22:45:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9B49A2BE78 for ; Fri, 28 Sep 2018 22:45:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8EDE22BE81; Fri, 28 Sep 2018 22:45:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3D21D2BE78 for ; Fri, 28 Sep 2018 22:45:09 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 350042115C089; Fri, 28 Sep 2018 15:45:09 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.31; helo=mga06.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 11BF0211518D1 for ; Fri, 28 Sep 2018 15:45:07 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Sep 2018 15:45:06 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,316,1534834800"; d="scan'208";a="93053198" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by fmsmga004.fm.intel.com with ESMTP; 28 Sep 2018 15:45:06 -0700 Subject: [PATCH v2 4/5] libnvdimm: add overwrite status notification From: Dave Jiang To: dan.j.williams@intel.com Date: Fri, 28 Sep 2018 15:45:06 -0700 Message-ID: <153817470623.19407.2154312383983084713.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> References: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Adding sysfs notification for when overwrite has completed to allow user monitoring app to be aware of overwrite completion status. Signed-off-by: Dave Jiang --- drivers/acpi/nfit/core.c | 5 +++++ drivers/nvdimm/dimm_devs.c | 12 ++++++++++++ drivers/nvdimm/nd-core.h | 1 + include/linux/libnvdimm.h | 1 + 4 files changed, 19 insertions(+) diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index b7773c70ee81..93c044527994 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -1950,6 +1950,11 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) if (!nvdimm) continue; + rc = nvdimm_setup_security_events(nvdimm); + if (rc < 0) + dev_warn(acpi_desc->dev, + "no security event setup failed\n"); + nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit"); if (nfit_kernfs) nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs, diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 73f7e879d6e0..12bafa3ba8f9 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -211,6 +211,8 @@ static void nvdimm_overwrite_query(struct work_struct *work) else dev_info(&nvdimm->dev, "Overwrite completed\n"); + if (nvdimm->overwrite_state) + sysfs_notify_dirent(nvdimm->overwrite_state); nvdimm->overwrite_tmo = 0; nvdimm_clear_security_busy(&nvdimm->dev); nvdimm_security_get_state(&nvdimm->dev); @@ -1134,6 +1136,16 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, } EXPORT_SYMBOL_GPL(nvdimm_create); +int nvdimm_setup_security_events(struct nvdimm *nvdimm) +{ + nvdimm->overwrite_state = sysfs_get_dirent(nvdimm->dev.kobj.sd, + "security"); + if (!nvdimm->overwrite_state) + return -ENODEV; + return 0; +} +EXPORT_SYMBOL_GPL(nvdimm_setup_security_events); + int alias_dpa_busy(struct device *dev, void *data) { resource_size_t map_end, blk_start, new; diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index efc7eb9e624c..043016f41156 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -48,6 +48,7 @@ struct nvdimm { struct key *key; struct delayed_work dwork; unsigned int overwrite_tmo; + struct kernfs_node *overwrite_state; }; /** diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index b59ff6b798b2..baf33b74cddf 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -218,6 +218,7 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, unsigned long cmd_mask, int num_flush, struct resource *flush_wpq, const char *dimm_id, const struct nvdimm_security_ops *sec_ops); +int nvdimm_setup_security_events(struct nvdimm *nvdimm); const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd); const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd); u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd, From patchwork Fri Sep 28 22:45:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10620499 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ADB931750 for ; Fri, 28 Sep 2018 22:45:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9AC932BE78 for ; Fri, 28 Sep 2018 22:45:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8F19D2BE81; Fri, 28 Sep 2018 22:45:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 56A052BE78 for ; Fri, 28 Sep 2018 22:45:13 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 4E0102115C086; Fri, 28 Sep 2018 15:45:13 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.115; helo=mga14.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org 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 ml01.01.org (Postfix) with ESMTPS id 53E6721106FA6 for ; Fri, 28 Sep 2018 15:45:12 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Sep 2018 15:45:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,316,1534834800"; d="scan'208";a="266900320" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by fmsmga005.fm.intel.com with ESMTP; 28 Sep 2018 15:45:11 -0700 Subject: [PATCH v2 5/5] libnvdimm: add documentation for ovewrite From: Dave Jiang To: dan.j.williams@intel.com Date: Fri, 28 Sep 2018 15:45:11 -0700 Message-ID: <153817471166.19407.8554249441903250990.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> References: <153817460190.19407.1009470794996360570.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Add overwrite command usages to security documentation. Signed-off-by: Dave Jiang --- Documentation/nvdimm/security.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/nvdimm/security.txt b/Documentation/nvdimm/security.txt index 50cbb6cb96a1..ded5f0e3f7c3 100644 --- a/Documentation/nvdimm/security.txt +++ b/Documentation/nvdimm/security.txt @@ -91,6 +91,17 @@ its keyid should be passed in via sysfs. The command format for doing a secure erase is: erase +9. Overwrite +------------ +The command format for doing an overwrite is: +overwrite + +Overwrite can be done without a key if security is not enabled. A key serial +of 0 can be passed in to indicate no key. + +The sysfs attribute "security" can be polled to wait on overwrite completion. +Overwrite can last tens of minutes or more depending on nvdimm size. + An "old" key with the passphrase payload that is tied to the nvdimm should be injected with a key description that does not have the "nvdimm:" prefix and its keyid should be passed in via sysfs.