Skip to content

Commit 9814143

Browse files
committed
Merge tag 'nvme-6.12-2024-09-06' of git://git.infradead.org/nvme into for-6.12/block
Pull NVMe updates from Keith: "nvme updates for Linux 6.12 - Asynchronous namespace scanning (Stuart) - TCP TLS updates (Hannes) - RDMA queue controller validation (Niklas) - Align field names to the spec (Anuj) - Metadata support validation (Puranjay)" * tag 'nvme-6.12-2024-09-06' of git://git.infradead.org/nvme: nvme: fix metadata handling in nvme-passthrough nvme: rename apptag and appmask to lbat and lbatm nvme-rdma: send cntlid in the RDMA_CM_REQUEST Private Data nvme-target: do not check authentication status for admin commands twice nvmet-auth: allow to clear DH-HMAC-CHAP keys nvme-sysfs: add 'tls_keyring' attribute nvme-sysfs: add 'tls_configured_key' sysfs attribute nvme: split off TLS sysfs attributes into a separate group nvme: add a newline to the 'tls_key' sysfs attribute nvme-tcp: check for invalidated or revoked key nvme-tcp: sanitize TLS key handling nvme-keyring: restrict match length for version '1' identifiers nvme_core: scan namespaces asynchronously
2 parents 68d20eb + 7c2fd76 commit 9814143

File tree

15 files changed

+250
-73
lines changed

15 files changed

+250
-73
lines changed

drivers/nvme/common/keyring.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,28 @@ key_serial_t nvme_keyring_id(void)
2020
}
2121
EXPORT_SYMBOL_GPL(nvme_keyring_id);
2222

23+
static bool nvme_tls_psk_revoked(struct key *psk)
24+
{
25+
return test_bit(KEY_FLAG_REVOKED, &psk->flags) ||
26+
test_bit(KEY_FLAG_INVALIDATED, &psk->flags);
27+
}
28+
29+
struct key *nvme_tls_key_lookup(key_serial_t key_id)
30+
{
31+
struct key *key = key_lookup(key_id);
32+
33+
if (IS_ERR(key)) {
34+
pr_err("key id %08x not found\n", key_id);
35+
return key;
36+
}
37+
if (nvme_tls_psk_revoked(key)) {
38+
pr_err("key id %08x revoked\n", key_id);
39+
return ERR_PTR(-EKEYREVOKED);
40+
}
41+
return key;
42+
}
43+
EXPORT_SYMBOL_GPL(nvme_tls_key_lookup);
44+
2345
static void nvme_tls_psk_describe(const struct key *key, struct seq_file *m)
2446
{
2547
seq_puts(m, key->description);
@@ -36,14 +58,12 @@ static bool nvme_tls_psk_match(const struct key *key,
3658
pr_debug("%s: no key description\n", __func__);
3759
return false;
3860
}
39-
match_len = strlen(key->description);
40-
pr_debug("%s: id %s len %zd\n", __func__, key->description, match_len);
41-
4261
if (!match_data->raw_data) {
4362
pr_debug("%s: no match data\n", __func__);
4463
return false;
4564
}
4665
match_id = match_data->raw_data;
66+
match_len = strlen(match_id);
4767
pr_debug("%s: match '%s' '%s' len %zd\n",
4868
__func__, match_id, key->description, match_len);
4969
return !memcmp(key->description, match_id, match_len);
@@ -71,7 +91,7 @@ static struct key_type nvme_tls_psk_key_type = {
7191

7292
static struct key *nvme_tls_psk_lookup(struct key *keyring,
7393
const char *hostnqn, const char *subnqn,
74-
int hmac, bool generated)
94+
u8 hmac, u8 psk_ver, bool generated)
7595
{
7696
char *identity;
7797
size_t identity_len = (NVMF_NQN_SIZE) * 2 + 11;
@@ -82,8 +102,8 @@ static struct key *nvme_tls_psk_lookup(struct key *keyring,
82102
if (!identity)
83103
return ERR_PTR(-ENOMEM);
84104

85-
snprintf(identity, identity_len, "NVMe0%c%02d %s %s",
86-
generated ? 'G' : 'R', hmac, hostnqn, subnqn);
105+
snprintf(identity, identity_len, "NVMe%u%c%02u %s %s",
106+
psk_ver, generated ? 'G' : 'R', hmac, hostnqn, subnqn);
87107

88108
if (!keyring)
89109
keyring = nvme_keyring;
@@ -107,21 +127,38 @@ static struct key *nvme_tls_psk_lookup(struct key *keyring,
107127
/*
108128
* NVMe PSK priority list
109129
*
110-
* 'Retained' PSKs (ie 'generated == false')
111-
* should be preferred to 'generated' PSKs,
112-
* and SHA-384 should be preferred to SHA-256.
130+
* 'Retained' PSKs (ie 'generated == false') should be preferred to 'generated'
131+
* PSKs, PSKs with hash (psk_ver 1) should be preferred to PSKs without hash
132+
* (psk_ver 0), and SHA-384 should be preferred to SHA-256.
113133
*/
114134
static struct nvme_tls_psk_priority_list {
115135
bool generated;
136+
u8 psk_ver;
116137
enum nvme_tcp_tls_cipher cipher;
117138
} nvme_tls_psk_prio[] = {
118139
{ .generated = false,
140+
.psk_ver = 1,
141+
.cipher = NVME_TCP_TLS_CIPHER_SHA384, },
142+
{ .generated = false,
143+
.psk_ver = 1,
144+
.cipher = NVME_TCP_TLS_CIPHER_SHA256, },
145+
{ .generated = false,
146+
.psk_ver = 0,
119147
.cipher = NVME_TCP_TLS_CIPHER_SHA384, },
120148
{ .generated = false,
149+
.psk_ver = 0,
150+
.cipher = NVME_TCP_TLS_CIPHER_SHA256, },
151+
{ .generated = true,
152+
.psk_ver = 1,
153+
.cipher = NVME_TCP_TLS_CIPHER_SHA384, },
154+
{ .generated = true,
155+
.psk_ver = 1,
121156
.cipher = NVME_TCP_TLS_CIPHER_SHA256, },
122157
{ .generated = true,
158+
.psk_ver = 0,
123159
.cipher = NVME_TCP_TLS_CIPHER_SHA384, },
124160
{ .generated = true,
161+
.psk_ver = 0,
125162
.cipher = NVME_TCP_TLS_CIPHER_SHA256, },
126163
};
127164

@@ -137,10 +174,11 @@ key_serial_t nvme_tls_psk_default(struct key *keyring,
137174

138175
for (prio = 0; prio < ARRAY_SIZE(nvme_tls_psk_prio); prio++) {
139176
bool generated = nvme_tls_psk_prio[prio].generated;
177+
u8 ver = nvme_tls_psk_prio[prio].psk_ver;
140178
enum nvme_tcp_tls_cipher cipher = nvme_tls_psk_prio[prio].cipher;
141179

142180
tls_key = nvme_tls_psk_lookup(keyring, hostnqn, subnqn,
143-
cipher, generated);
181+
cipher, ver, generated);
144182
if (!IS_ERR(tls_key)) {
145183
tls_key_id = tls_key->serial;
146184
key_put(tls_key);

drivers/nvme/host/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ config NVME_HOST_AUTH
109109
bool "NVMe over Fabrics In-Band Authentication in host side"
110110
depends on NVME_CORE
111111
select NVME_AUTH
112+
select NVME_KEYRING if NVME_TCP_TLS
112113
help
113114
This provides support for NVMe over Fabrics In-Band Authentication in
114115
host side.

drivers/nvme/host/core.c

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2011-2014, Intel Corporation.
55
*/
66

7+
#include <linux/async.h>
78
#include <linux/blkdev.h>
89
#include <linux/blk-mq.h>
910
#include <linux/blk-integrity.h>
@@ -986,8 +987,8 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
986987
cmnd->rw.length =
987988
cpu_to_le16((blk_rq_bytes(req) >> ns->head->lba_shift) - 1);
988989
cmnd->rw.reftag = 0;
989-
cmnd->rw.apptag = 0;
990-
cmnd->rw.appmask = 0;
990+
cmnd->rw.lbat = 0;
991+
cmnd->rw.lbatm = 0;
991992

992993
if (ns->head->ms) {
993994
/*
@@ -4040,6 +4041,35 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
40404041
}
40414042
}
40424043

4044+
/**
4045+
* struct async_scan_info - keeps track of controller & NSIDs to scan
4046+
* @ctrl: Controller on which namespaces are being scanned
4047+
* @next_nsid: Index of next NSID to scan in ns_list
4048+
* @ns_list: Pointer to list of NSIDs to scan
4049+
*
4050+
* Note: There is a single async_scan_info structure shared by all instances
4051+
* of nvme_scan_ns_async() scanning a given controller, so the atomic
4052+
* operations on next_nsid are critical to ensure each instance scans a unique
4053+
* NSID.
4054+
*/
4055+
struct async_scan_info {
4056+
struct nvme_ctrl *ctrl;
4057+
atomic_t next_nsid;
4058+
__le32 *ns_list;
4059+
};
4060+
4061+
static void nvme_scan_ns_async(void *data, async_cookie_t cookie)
4062+
{
4063+
struct async_scan_info *scan_info = data;
4064+
int idx;
4065+
u32 nsid;
4066+
4067+
idx = (u32)atomic_fetch_inc(&scan_info->next_nsid);
4068+
nsid = le32_to_cpu(scan_info->ns_list[idx]);
4069+
4070+
nvme_scan_ns(scan_info->ctrl, nsid);
4071+
}
4072+
40434073
static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
40444074
unsigned nsid)
40454075
{
@@ -4066,11 +4096,15 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl)
40664096
__le32 *ns_list;
40674097
u32 prev = 0;
40684098
int ret = 0, i;
4099+
ASYNC_DOMAIN(domain);
4100+
struct async_scan_info scan_info;
40694101

40704102
ns_list = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
40714103
if (!ns_list)
40724104
return -ENOMEM;
40734105

4106+
scan_info.ctrl = ctrl;
4107+
scan_info.ns_list = ns_list;
40744108
for (;;) {
40754109
struct nvme_command cmd = {
40764110
.identify.opcode = nvme_admin_identify,
@@ -4086,19 +4120,23 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl)
40864120
goto free;
40874121
}
40884122

4123+
atomic_set(&scan_info.next_nsid, 0);
40894124
for (i = 0; i < nr_entries; i++) {
40904125
u32 nsid = le32_to_cpu(ns_list[i]);
40914126

40924127
if (!nsid) /* end of the list? */
40934128
goto out;
4094-
nvme_scan_ns(ctrl, nsid);
4129+
async_schedule_domain(nvme_scan_ns_async, &scan_info,
4130+
&domain);
40954131
while (++prev < nsid)
40964132
nvme_ns_remove_by_nsid(ctrl, prev);
40974133
}
4134+
async_synchronize_full_domain(&domain);
40984135
}
40994136
out:
41004137
nvme_remove_invalid_namespaces(ctrl, prev);
41014138
free:
4139+
async_synchronize_full_domain(&domain);
41024140
kfree(ns_list);
41034141
return ret;
41044142
}
@@ -4677,7 +4715,6 @@ static void nvme_free_ctrl(struct device *dev)
46774715

46784716
if (!subsys || ctrl->instance != subsys->instance)
46794717
ida_free(&nvme_instance_ida, ctrl->instance);
4680-
key_put(ctrl->tls_key);
46814718
nvme_free_cels(ctrl);
46824719
nvme_mpath_uninit(ctrl);
46834720
cleanup_srcu_struct(&ctrl->srcu);

drivers/nvme/host/fabrics.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ static struct key *nvmf_parse_key(int key_id)
665665
return ERR_PTR(-EINVAL);
666666
}
667667

668-
key = key_lookup(key_id);
668+
key = nvme_tls_key_lookup(key_id);
669669
if (IS_ERR(key))
670670
pr_err("key id %08x not found\n", key_id);
671671
else

drivers/nvme/host/ioctl.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2017-2021 Christoph Hellwig.
55
*/
66
#include <linux/bio-integrity.h>
7+
#include <linux/blk-integrity.h>
78
#include <linux/ptrace.h> /* for force_successful_syscall_return */
89
#include <linux/nvme_ioctl.h>
910
#include <linux/io_uring/cmd.h>
@@ -119,9 +120,14 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
119120
struct request_queue *q = req->q;
120121
struct nvme_ns *ns = q->queuedata;
121122
struct block_device *bdev = ns ? ns->disk->part0 : NULL;
123+
bool supports_metadata = bdev && blk_get_integrity(bdev->bd_disk);
124+
bool has_metadata = meta_buffer && meta_len;
122125
struct bio *bio = NULL;
123126
int ret;
124127

128+
if (has_metadata && !supports_metadata)
129+
return -EINVAL;
130+
125131
if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
126132
struct iov_iter iter;
127133

@@ -143,15 +149,15 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
143149
goto out;
144150

145151
bio = req->bio;
146-
if (bdev) {
152+
if (bdev)
147153
bio_set_dev(bio, bdev);
148-
if (meta_buffer && meta_len) {
149-
ret = bio_integrity_map_user(bio, meta_buffer, meta_len,
150-
meta_seed);
151-
if (ret)
152-
goto out_unmap;
153-
req->cmd_flags |= REQ_INTEGRITY;
154-
}
154+
155+
if (has_metadata) {
156+
ret = bio_integrity_map_user(bio, meta_buffer, meta_len,
157+
meta_seed);
158+
if (ret)
159+
goto out_unmap;
160+
req->cmd_flags |= REQ_INTEGRITY;
155161
}
156162

157163
return ret;
@@ -260,8 +266,8 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
260266
c.rw.control = cpu_to_le16(io.control);
261267
c.rw.dsmgmt = cpu_to_le32(io.dsmgmt);
262268
c.rw.reftag = cpu_to_le32(io.reftag);
263-
c.rw.apptag = cpu_to_le16(io.apptag);
264-
c.rw.appmask = cpu_to_le16(io.appmask);
269+
c.rw.lbat = cpu_to_le16(io.apptag);
270+
c.rw.lbatm = cpu_to_le16(io.appmask);
265271

266272
return nvme_submit_user_cmd(ns->queue, &c, io.addr, length, metadata,
267273
meta_len, lower_32_bits(io.slba), NULL, 0, 0);

drivers/nvme/host/nvme.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ struct nvme_ctrl {
373373
struct nvme_dhchap_key *ctrl_key;
374374
u16 transaction;
375375
#endif
376-
struct key *tls_key;
376+
key_serial_t tls_pskid;
377377

378378
/* Power saving configuration */
379379
u64 ps_max_latency_us;

drivers/nvme/host/rdma.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,8 +1363,8 @@ static void nvme_rdma_set_sig_domain(struct blk_integrity *bi,
13631363
if (control & NVME_RW_PRINFO_PRCHK_REF)
13641364
domain->sig.dif.ref_remap = true;
13651365

1366-
domain->sig.dif.app_tag = le16_to_cpu(cmd->rw.apptag);
1367-
domain->sig.dif.apptag_check_mask = le16_to_cpu(cmd->rw.appmask);
1366+
domain->sig.dif.app_tag = le16_to_cpu(cmd->rw.lbat);
1367+
domain->sig.dif.apptag_check_mask = le16_to_cpu(cmd->rw.lbatm);
13681368
domain->sig.dif.app_escape = true;
13691369
if (pi_type == NVME_NS_DPS_PI_TYPE3)
13701370
domain->sig.dif.ref_escape = true;
@@ -1876,6 +1876,8 @@ static int nvme_rdma_route_resolved(struct nvme_rdma_queue *queue)
18761876
*/
18771877
priv.hrqsize = cpu_to_le16(queue->queue_size);
18781878
priv.hsqsize = cpu_to_le16(queue->ctrl->ctrl.sqsize);
1879+
/* cntlid should only be set when creating an I/O queue */
1880+
priv.cntlid = cpu_to_le16(ctrl->ctrl.cntlid);
18791881
}
18801882

18811883
ret = rdma_connect_locked(queue->cm_id, &param);

0 commit comments

Comments
 (0)