From: Davidlohr Bueso <dave@stgolabs.net>
To: vishal.l.verma@intel.com
Cc: y-goto@fujitsu.com, dave.jiang@intel.com,
dan.j.williams@intel.com, linux-cxl@vger.kernel.org,
dave@stgolabs.net
Subject: [PATCH -ndctl] cxl/memdev: Introduce sanitize-memdev functionality
Date: Sat, 28 Sep 2024 14:16:42 -0700 [thread overview]
Message-ID: <20240928211643.140264-1-dave@stgolabs.net> (raw)
Add a new cxl_memdev_sanitize() to libcxl to support triggering memory
device sanitation, in either Sanitize and/or Secure Erase, per the
CXL 3.0 spec.
This is analogous to 'ndctl sanitize-dimm'.
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
---
Documentation/cxl/cxl-sanitize-memdev.txt | 59 +++++++++++++++++++++++
Documentation/cxl/meson.build | 1 +
cxl/builtin.h | 1 +
cxl/cxl.c | 1 +
cxl/lib/libcxl.c | 15 ++++++
cxl/lib/libcxl.sym | 1 +
cxl/libcxl.h | 1 +
cxl/memdev.c | 48 ++++++++++++++++++
8 files changed, 127 insertions(+)
create mode 100644 Documentation/cxl/cxl-sanitize-memdev.txt
diff --git a/Documentation/cxl/cxl-sanitize-memdev.txt b/Documentation/cxl/cxl-sanitize-memdev.txt
new file mode 100644
index 000000000000..22212898542a
--- /dev/null
+++ b/Documentation/cxl/cxl-sanitize-memdev.txt
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+
+cxl-sanitize-memdev(1)
+======================
+
+NAME
+----
+cxl-sanitize-memdev - Perform a cryptographic destruction or sanitization
+of the contents of the given memdev(s).
+
+SYNOPSIS
+--------
+[verse]
+'cxl sanitize-memdev <mem0> [<mem1>..<memN>] [<options>]'
+
+DESCRIPTION
+-----------
+The 'sanitize-memdev' command performs two different methods of
+sanitization, per the CXL 3.0+ specification. It is required that
+the memdev be disabled before sanitizing, such that the device
+cannot be actively decoding any HPA ranges at the time.
+
+The default is 'sanitize', but additionally, a 'secure-erase'
+option is available. If both types of operations are supplied,
+then the 'secure-erase' is performed before 'sanitize'.
+
+OPTIONS
+-------
+
+include::bus-option.txt[]
+
+-e::
+--secure-erase::
+ Erase user data by changing the media encryption keys for all user
+ data areas of the device.
+
+-s::
+--sanitize::
+ Sanitize the device to securely re-purpose or decommission it. This is
+ done by ensuring that all user data and meta data, whether it resides
+ in persistent capacity, volatile capacity, or the label storage area,
+ is made permanently unavailable by whatever means is appropriate for
+ the media type.
+
+ With this option, the sanitization request is merely submitted to the
+ kernel, and the completion is asynchronous. Depending on the medium and
+ capacity, sanitize may take tens of minutes to many hours. Subsequently,
+ 'cxl wait-sanitize’ can be used to wait for the memdevs that are under
+ the sanitization.
+
+include::verbose-option.txt[]
+
+include::../copyright.txt[]
+
+SEE ALSO
+--------
+linkcxl:cxl-wait-sanitize[1],
+linkcxl:cxl-disable-memdev[1],
+linkcxl:cxl-list[1],
diff --git a/Documentation/cxl/meson.build b/Documentation/cxl/meson.build
index 8085c1c2c87e..99e6ee782a1c 100644
--- a/Documentation/cxl/meson.build
+++ b/Documentation/cxl/meson.build
@@ -49,6 +49,7 @@ cxl_manpages = [
'cxl-monitor.txt',
'cxl-update-firmware.txt',
'cxl-set-alert-config.txt',
+ 'cxl-sanitize-memdev.txt',
'cxl-wait-sanitize.txt',
]
diff --git a/cxl/builtin.h b/cxl/builtin.h
index c483f301e5e0..29c8ad2a0ad9 100644
--- a/cxl/builtin.h
+++ b/cxl/builtin.h
@@ -16,6 +16,7 @@ int cmd_reserve_dpa(int argc, const char **argv, struct cxl_ctx *ctx);
int cmd_free_dpa(int argc, const char **argv, struct cxl_ctx *ctx);
int cmd_update_fw(int argc, const char **argv, struct cxl_ctx *ctx);
int cmd_set_alert_config(int argc, const char **argv, struct cxl_ctx *ctx);
+int cmd_sanitize_memdev(int argc, const char **argv, struct cxl_ctx *ctx);
int cmd_wait_sanitize(int argc, const char **argv, struct cxl_ctx *ctx);
int cmd_disable_port(int argc, const char **argv, struct cxl_ctx *ctx);
int cmd_enable_port(int argc, const char **argv, struct cxl_ctx *ctx);
diff --git a/cxl/cxl.c b/cxl/cxl.c
index 16436671dc53..9c9f217c5a93 100644
--- a/cxl/cxl.c
+++ b/cxl/cxl.c
@@ -80,6 +80,7 @@ static struct cmd_struct commands[] = {
{ "disable-region", .c_fn = cmd_disable_region },
{ "destroy-region", .c_fn = cmd_destroy_region },
{ "monitor", .c_fn = cmd_monitor },
+ { "sanitize-memdev", .c_fn = cmd_sanitize_memdev },
};
int main(int argc, const char **argv)
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index 91eedd1c4688..4f44bf1b6185 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -1414,6 +1414,21 @@ CXL_EXPORT int cxl_memdev_get_id(struct cxl_memdev *memdev)
return memdev->id;
}
+CXL_EXPORT int cxl_memdev_sanitize(struct cxl_memdev *memdev, char *op)
+{
+ struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
+ char *path = memdev->dev_buf;
+ int len = memdev->buf_len;
+
+ if (snprintf(path, len,
+ "%s/security/%s", memdev->dev_path, op) >= len) {
+ err(ctx, "%s: buffer too small!\n",
+ cxl_memdev_get_devname(memdev));
+ return -ERANGE;
+ }
+ return sysfs_write_attr(ctx, path, "1\n");
+}
+
CXL_EXPORT int cxl_memdev_wait_sanitize(struct cxl_memdev *memdev,
int timeout_ms)
{
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index 304d7fa735d4..89a4c63cb874 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -281,4 +281,5 @@ global:
cxl_memdev_get_ram_qos_class;
cxl_region_qos_class_mismatch;
cxl_port_decoders_committed;
+ cxl_memdev_sanitize;
} LIBCXL_6;
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index fc6dd0085440..a722bab8a65b 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -79,6 +79,7 @@ bool cxl_memdev_fw_update_in_progress(struct cxl_memdev *memdev);
size_t cxl_memdev_fw_update_get_remaining(struct cxl_memdev *memdev);
int cxl_memdev_update_fw(struct cxl_memdev *memdev, const char *fw_path);
int cxl_memdev_cancel_fw_update(struct cxl_memdev *memdev);
+int cxl_memdev_sanitize(struct cxl_memdev *memdev, char *op);
int cxl_memdev_wait_sanitize(struct cxl_memdev *memdev, int timeout_ms);
/* ABI spelling mistakes are forever */
diff --git a/cxl/memdev.c b/cxl/memdev.c
index 6e44d1578d03..60d1515b19f3 100644
--- a/cxl/memdev.c
+++ b/cxl/memdev.c
@@ -35,6 +35,8 @@ static struct parameters {
bool align;
bool cancel;
bool wait;
+ bool sanitize;
+ bool secure_erase;
const char *type;
const char *size;
const char *decoder_filter;
@@ -160,6 +162,12 @@ OPT_STRING('\0', "pmem-err-alert", \
¶m.corrected_pmem_err_alert, "'on' or 'off'", \
"enable or disable corrected pmem error warning alert")
+#define SANITIZE_OPTIONS() \
+OPT_BOOLEAN('e', "secure-erase", ¶m.secure_erase, \
+ "secure erase a memdev"), \
+OPT_BOOLEAN('s', "sanitize", ¶m.sanitize, \
+ "sanitize a memdev")
+
#define WAIT_SANITIZE_OPTIONS() \
OPT_INTEGER('t', "timeout", ¶m.timeout, \
"time in milliseconds to wait for overwrite completion (default: infinite)")
@@ -226,6 +234,12 @@ static const struct option set_alert_options[] = {
OPT_END(),
};
+static const struct option sanitize_options[] = {
+ BASE_OPTIONS(),
+ SANITIZE_OPTIONS(),
+ OPT_END(),
+};
+
static const struct option wait_sanitize_options[] = {
BASE_OPTIONS(),
WAIT_SANITIZE_OPTIONS(),
@@ -772,6 +786,27 @@ out_err:
return rc;
}
+static int action_sanitize_memdev(struct cxl_memdev *memdev,
+ struct action_context *actx)
+{
+ int rc = 0;
+
+ if (cxl_memdev_is_enabled(memdev))
+ return -EBUSY;
+
+ /* let Sanitize be the default */
+ if (!param.secure_erase && !param.sanitize)
+ param.sanitize = true;
+ if (param.secure_erase)
+ rc = cxl_memdev_sanitize(memdev, "erase");
+ if (param.sanitize)
+ rc = cxl_memdev_sanitize(memdev, "sanitize");
+ else
+ rc = -EINVAL;
+
+ return rc;
+}
+
static int action_wait_sanitize(struct cxl_memdev *memdev,
struct action_context *actx)
{
@@ -1228,6 +1263,19 @@ int cmd_set_alert_config(int argc, const char **argv, struct cxl_ctx *ctx)
return count >= 0 ? 0 : EXIT_FAILURE;
}
+int cmd_sanitize_memdev(int argc, const char **argv, struct cxl_ctx *ctx)
+{
+ int count = memdev_action(
+ argc, argv, ctx, action_sanitize_memdev, sanitize_options,
+ "cxl sanitize-memdev <mem0> [<mem1>..<memn>] [<options>]");
+
+ log_info(&ml, "sanitize %s on %d mem device%s\n",
+ count >= 0 ? "completed/started" : "failed",
+ count >= 0 ? count : 0, count > 1 ? "s" : "");
+
+ return count >= 0 ? 0 : EXIT_FAILURE;
+}
+
int cmd_wait_sanitize(int argc, const char **argv, struct cxl_ctx *ctx)
{
int count = memdev_action(
--
2.46.1
next reply other threads:[~2024-09-28 21:56 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-28 21:16 Davidlohr Bueso [this message]
2024-09-30 17:36 ` [PATCH -ndctl] cxl/memdev: Introduce sanitize-memdev functionality Alison Schofield
2024-09-30 19:29 ` Davidlohr Bueso
2024-09-30 21:39 ` Davidlohr Bueso
2025-02-18 16:34 ` Alison Schofield
2025-02-18 16:55 ` Davidlohr Bueso
2024-12-10 7:38 ` Yasunori Gotou (Fujitsu)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240928211643.140264-1-dave@stgolabs.net \
--to=dave@stgolabs.net \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=vishal.l.verma@intel.com \
--cc=y-goto@fujitsu.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox