Skip to content

Commit f4a1e8e

Browse files
committed
Merge tag 'block-6.12-20241101' of git://git.kernel.dk/linux
Pull block fixes from Jens Axboe: - Fixup for a recent blk_rq_map_user_bvec() patch - NVMe pull request via Keith: - Spec compliant identification fix (Keith) - Module parameter to enable backward compatibility on unusual namespace formats (Keith) - Target double free fix when using keys (Vitaliy) - Passthrough command error handling fix (Keith) * tag 'block-6.12-20241101' of git://git.kernel.dk/linux: nvme: re-fix error-handling for io_uring nvme-passthrough nvmet-auth: assign dh_key to NULL after kfree_sensitive nvme: module parameter to disable pi with offsets block: fix queue limits checks in blk_rq_map_user_bvec for real nvme: enhance cns version checking
2 parents f0d3699 + d0c6cc6 commit f4a1e8e

File tree

4 files changed

+65
-55
lines changed

4 files changed

+65
-55
lines changed

block/blk-map.c

+17-39
Original file line numberDiff line numberDiff line change
@@ -561,55 +561,33 @@ EXPORT_SYMBOL(blk_rq_append_bio);
561561
/* Prepare bio for passthrough IO given ITER_BVEC iter */
562562
static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter)
563563
{
564-
struct request_queue *q = rq->q;
565-
size_t nr_iter = iov_iter_count(iter);
566-
size_t nr_segs = iter->nr_segs;
567-
struct bio_vec *bvecs, *bvprvp = NULL;
568-
const struct queue_limits *lim = &q->limits;
569-
unsigned int nsegs = 0, bytes = 0;
564+
const struct queue_limits *lim = &rq->q->limits;
565+
unsigned int max_bytes = lim->max_hw_sectors << SECTOR_SHIFT;
566+
unsigned int nsegs;
570567
struct bio *bio;
571-
size_t i;
568+
int ret;
572569

573-
if (!nr_iter || (nr_iter >> SECTOR_SHIFT) > queue_max_hw_sectors(q))
574-
return -EINVAL;
575-
if (nr_segs > queue_max_segments(q))
570+
if (!iov_iter_count(iter) || iov_iter_count(iter) > max_bytes)
576571
return -EINVAL;
577572

578-
/* no iovecs to alloc, as we already have a BVEC iterator */
573+
/* reuse the bvecs from the iterator instead of allocating new ones */
579574
bio = blk_rq_map_bio_alloc(rq, 0, GFP_KERNEL);
580-
if (bio == NULL)
575+
if (!bio)
581576
return -ENOMEM;
582-
583577
bio_iov_bvec_set(bio, (struct iov_iter *)iter);
584-
blk_rq_bio_prep(rq, bio, nr_segs);
585-
586-
/* loop to perform a bunch of sanity checks */
587-
bvecs = (struct bio_vec *)iter->bvec;
588-
for (i = 0; i < nr_segs; i++) {
589-
struct bio_vec *bv = &bvecs[i];
590-
591-
/*
592-
* If the queue doesn't support SG gaps and adding this
593-
* offset would create a gap, fallback to copy.
594-
*/
595-
if (bvprvp && bvec_gap_to_prev(lim, bvprvp, bv->bv_offset)) {
596-
blk_mq_map_bio_put(bio);
597-
return -EREMOTEIO;
598-
}
599-
/* check full condition */
600-
if (nsegs >= nr_segs || bytes > UINT_MAX - bv->bv_len)
601-
goto put_bio;
602-
if (bytes + bv->bv_len > nr_iter)
603-
break;
604578

605-
nsegs++;
606-
bytes += bv->bv_len;
607-
bvprvp = bv;
579+
/* check that the data layout matches the hardware restrictions */
580+
ret = bio_split_rw_at(bio, lim, &nsegs, max_bytes);
581+
if (ret) {
582+
/* if we would have to split the bio, copy instead */
583+
if (ret > 0)
584+
ret = -EREMOTEIO;
585+
blk_mq_map_bio_put(bio);
586+
return ret;
608587
}
588+
589+
blk_rq_bio_prep(rq, bio, nsegs);
609590
return 0;
610-
put_bio:
611-
blk_mq_map_bio_put(bio);
612-
return -EINVAL;
613591
}
614592

615593
/**

drivers/nvme/host/core.c

+42-14
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ module_param(apst_secondary_latency_tol_us, ulong, 0644);
9191
MODULE_PARM_DESC(apst_secondary_latency_tol_us,
9292
"secondary APST latency tolerance in us");
9393

94+
/*
95+
* Older kernels didn't enable protection information if it was at an offset.
96+
* Newer kernels do, so it breaks reads on the upgrade if such formats were
97+
* used in prior kernels since the metadata written did not contain a valid
98+
* checksum.
99+
*/
100+
static bool disable_pi_offsets = false;
101+
module_param(disable_pi_offsets, bool, 0444);
102+
MODULE_PARM_DESC(disable_pi_offsets,
103+
"disable protection information if it has an offset");
104+
94105
/*
95106
* nvme_wq - hosts nvme related works that are not reset or delete
96107
* nvme_reset_wq - hosts nvme reset works
@@ -1390,17 +1401,30 @@ static void nvme_update_keep_alive(struct nvme_ctrl *ctrl,
13901401
nvme_start_keep_alive(ctrl);
13911402
}
13921403

1393-
/*
1394-
* In NVMe 1.0 the CNS field was just a binary controller or namespace
1395-
* flag, thus sending any new CNS opcodes has a big chance of not working.
1396-
* Qemu unfortunately had that bug after reporting a 1.1 version compliance
1397-
* (but not for any later version).
1398-
*/
1399-
static bool nvme_ctrl_limited_cns(struct nvme_ctrl *ctrl)
1404+
static bool nvme_id_cns_ok(struct nvme_ctrl *ctrl, u8 cns)
14001405
{
1401-
if (ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)
1402-
return ctrl->vs < NVME_VS(1, 2, 0);
1403-
return ctrl->vs < NVME_VS(1, 1, 0);
1406+
/*
1407+
* The CNS field occupies a full byte starting with NVMe 1.2
1408+
*/
1409+
if (ctrl->vs >= NVME_VS(1, 2, 0))
1410+
return true;
1411+
1412+
/*
1413+
* NVMe 1.1 expanded the CNS value to two bits, which means values
1414+
* larger than that could get truncated and treated as an incorrect
1415+
* value.
1416+
*
1417+
* Qemu implemented 1.0 behavior for controllers claiming 1.1
1418+
* compliance, so they need to be quirked here.
1419+
*/
1420+
if (ctrl->vs >= NVME_VS(1, 1, 0) &&
1421+
!(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS))
1422+
return cns <= 3;
1423+
1424+
/*
1425+
* NVMe 1.0 used a single bit for the CNS value.
1426+
*/
1427+
return cns <= 1;
14041428
}
14051429

14061430
static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id)
@@ -1913,8 +1937,12 @@ static void nvme_configure_metadata(struct nvme_ctrl *ctrl,
19131937

19141938
if (head->pi_size && head->ms >= head->pi_size)
19151939
head->pi_type = id->dps & NVME_NS_DPS_PI_MASK;
1916-
if (!(id->dps & NVME_NS_DPS_PI_FIRST))
1917-
info->pi_offset = head->ms - head->pi_size;
1940+
if (!(id->dps & NVME_NS_DPS_PI_FIRST)) {
1941+
if (disable_pi_offsets)
1942+
head->pi_type = 0;
1943+
else
1944+
info->pi_offset = head->ms - head->pi_size;
1945+
}
19181946

19191947
if (ctrl->ops->flags & NVME_F_FABRICS) {
19201948
/*
@@ -3104,7 +3132,7 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl)
31043132
ctrl->max_zeroes_sectors = 0;
31053133

31063134
if (ctrl->subsys->subtype != NVME_NQN_NVME ||
3107-
nvme_ctrl_limited_cns(ctrl) ||
3135+
!nvme_id_cns_ok(ctrl, NVME_ID_CNS_CS_CTRL) ||
31083136
test_bit(NVME_CTRL_SKIP_ID_CNS_CS, &ctrl->flags))
31093137
return 0;
31103138

@@ -4200,7 +4228,7 @@ static void nvme_scan_work(struct work_struct *work)
42004228
}
42014229

42024230
mutex_lock(&ctrl->scan_lock);
4203-
if (nvme_ctrl_limited_cns(ctrl)) {
4231+
if (!nvme_id_cns_ok(ctrl, NVME_ID_CNS_NS_ACTIVE_LIST)) {
42044232
nvme_scan_ns_sequential(ctrl);
42054233
} else {
42064234
/*

drivers/nvme/host/ioctl.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,13 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
421421
struct io_uring_cmd *ioucmd = req->end_io_data;
422422
struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
423423

424-
if (nvme_req(req)->flags & NVME_REQ_CANCELLED)
424+
if (nvme_req(req)->flags & NVME_REQ_CANCELLED) {
425425
pdu->status = -EINTR;
426-
else
426+
} else {
427427
pdu->status = nvme_req(req)->status;
428+
if (!pdu->status)
429+
pdu->status = blk_status_to_errno(err);
430+
}
428431
pdu->result = le64_to_cpu(nvme_req(req)->result.u64);
429432

430433
/*

drivers/nvme/target/auth.c

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id)
115115
pr_debug("%s: ctrl %d failed to generate private key, err %d\n",
116116
__func__, ctrl->cntlid, ret);
117117
kfree_sensitive(ctrl->dh_key);
118+
ctrl->dh_key = NULL;
118119
return ret;
119120
}
120121
ctrl->dh_keysize = crypto_kpp_maxsize(ctrl->dh_tfm);

0 commit comments

Comments
 (0)