]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
nvme: Allow reauth from sysfs
authorAlistair Francis <alistair.francis@wdc.com>
Tue, 2 Dec 2025 05:17:55 +0000 (15:17 +1000)
committerKeith Busch <kbusch@kernel.org>
Fri, 27 Mar 2026 14:35:03 +0000 (07:35 -0700)
Allow userspace to trigger a reauth (REPLACETLSPSK) from sysfs.
This can be done by writing  a zero to the sysfs file.

echo 0 > /sys/devices/virtual/nvme-fabrics/ctl/nvme0/tls_configured_key

In order to use the new keys for the admin queue we call controller
reset. This isn't ideal, but I can't find a simpler way to reset the
admin queue TLS connection.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Documentation/ABI/testing/sysfs-nvme [new file with mode: 0644]
drivers/nvme/host/sysfs.c

diff --git a/Documentation/ABI/testing/sysfs-nvme b/Documentation/ABI/testing/sysfs-nvme
new file mode 100644 (file)
index 0000000..499d5f8
--- /dev/null
@@ -0,0 +1,13 @@
+What:          /sys/devices/virtual/nvme-fabrics/ctl/.../tls_configured_key
+Date:          November 2025
+KernelVersion: 6.19
+Contact:       Linux NVMe mailing list <linux-nvme@lists.infradead.org>
+Description:
+               The file is avaliable when using a secure concatanation
+               connection to a NVMe target. Reading the file will return
+               the serial of the currently negotiated key.
+
+               Writing 0 to the file will trigger a PSK reauthentication
+               (REPLACETLSPSK) with the target. After a reauthentication
+               the value returned by tls_configured_key will be the new
+               serial.
index 7a4b0924c3a21e7cd2e27d303c4d6b61a6146e3f..7bf2e972126b197fe808b73439b477d9f105943e 100644 (file)
@@ -829,7 +829,49 @@ static ssize_t tls_configured_key_show(struct device *dev,
 
        return sysfs_emit(buf, "%08x\n", key_serial(key));
 }
-static DEVICE_ATTR_RO(tls_configured_key);
+
+static ssize_t tls_configured_key_store(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+       struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+       int error, qid;
+
+       error = kstrtoint(buf, 10, &qid);
+       if (error)
+               return error;
+
+       /*
+        * We currently only allow userspace to write a `0` indicating
+        * generate a new key.
+        */
+       if (qid)
+               return -EINVAL;
+
+       if (!ctrl->opts || !ctrl->opts->concat)
+               return -EOPNOTSUPP;
+
+       error = nvme_auth_negotiate(ctrl, 0);
+       if (error < 0) {
+               nvme_reset_ctrl(ctrl);
+               return error;
+       }
+
+       error = nvme_auth_wait(ctrl, 0);
+       if (error < 0) {
+               nvme_reset_ctrl(ctrl);
+               return error;
+       }
+
+       /*
+        * We need to reset the TLS connection, so let's just
+        * reset the controller.
+        */
+       nvme_reset_ctrl(ctrl);
+
+       return count;
+}
+static DEVICE_ATTR_RW(tls_configured_key);
 
 static ssize_t tls_keyring_show(struct device *dev,
                struct device_attribute *attr, char *buf)