nvme fixes for Linux 6.12
- 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) -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE3Fbyvv+648XNRdHTPe3zGtjzRgkFAmcjnPcACgkQPe3zGtjz Rgk6dA/9FHPe5el/whNfJjYp65Gx7pUGD+7ObdI/4pQAQCBtJcV5opWBDK3W1qN5 j1wVGY3sC/f7+MPvVP72Fj9WKJ3+iyrihlACnUl9L33o52Q0pFUPi93Uyu4bvJ1U kRbsulomDK/EJk3hcEFtRX7TkEl9BguKKmdpPIvVfv9ADU8xvlowgeQUs0Ea4p2R j9YYAqXRUyquKulm57eSkZKXSZeD5sP82o9EXUzUSiGDFXt4YizrcIRDf+7497En vCweGmYjyW76jAVVphWDAk48MHHhdpDYQ7YwT+SbYoLxKJMOZe04ZJupxexIIpSD RenTOq5mbCdMRjjuv6ygITWTtZ0XKOHHJLBBKMSff6Q5Bxo6tGw9/8lT1rpUPqD4 gh/d9fZjgZG/3LAQmmdv2NGN9jDuPN0adTn5nzbEnhaeiyLysZUIA91xT63GaSTi +pYvr5RgTsCloUgQAMDSZVf/23o15Yvu3uP6GZuQ1hG1ZBDGU/WN+fm+Ta1n0cAz kjncor9EyM4rk7C5AufksVDE+17Zx+kfGuX1XBW+HBGBuFgrdGByrzLodF+AFtOC JdbVdH+z/Ez3/56910gYKCwAPRZt2j5KHZJHgXp+8FI/godsh+xCrT0PPTWkuuX9 bUd7l6GQv5GmV0QBxW/5FfiCxigA5wuAXyDZSm3Ah151cf+M/9A= =hs9+ -----END PGP SIGNATURE----- Merge tag 'nvme-6.12-2024-10-31' of git://git.infradead.org/nvme into block-6.12 Pull NVMe fixes from Keith: "nvme fixes for Linux 6.12 - 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 'nvme-6.12-2024-10-31' of git://git.infradead.org/nvme: 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 nvme: enhance cns version checking
This commit is contained in:
commit
d0c6cc6c6a
@ -91,6 +91,17 @@ module_param(apst_secondary_latency_tol_us, ulong, 0644);
|
||||
MODULE_PARM_DESC(apst_secondary_latency_tol_us,
|
||||
"secondary APST latency tolerance in us");
|
||||
|
||||
/*
|
||||
* Older kernels didn't enable protection information if it was at an offset.
|
||||
* Newer kernels do, so it breaks reads on the upgrade if such formats were
|
||||
* used in prior kernels since the metadata written did not contain a valid
|
||||
* checksum.
|
||||
*/
|
||||
static bool disable_pi_offsets = false;
|
||||
module_param(disable_pi_offsets, bool, 0444);
|
||||
MODULE_PARM_DESC(disable_pi_offsets,
|
||||
"disable protection information if it has an offset");
|
||||
|
||||
/*
|
||||
* nvme_wq - hosts nvme related works that are not reset or delete
|
||||
* nvme_reset_wq - hosts nvme reset works
|
||||
@ -1390,17 +1401,30 @@ static void nvme_update_keep_alive(struct nvme_ctrl *ctrl,
|
||||
nvme_start_keep_alive(ctrl);
|
||||
}
|
||||
|
||||
/*
|
||||
* In NVMe 1.0 the CNS field was just a binary controller or namespace
|
||||
* flag, thus sending any new CNS opcodes has a big chance of not working.
|
||||
* Qemu unfortunately had that bug after reporting a 1.1 version compliance
|
||||
* (but not for any later version).
|
||||
*/
|
||||
static bool nvme_ctrl_limited_cns(struct nvme_ctrl *ctrl)
|
||||
static bool nvme_id_cns_ok(struct nvme_ctrl *ctrl, u8 cns)
|
||||
{
|
||||
if (ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)
|
||||
return ctrl->vs < NVME_VS(1, 2, 0);
|
||||
return ctrl->vs < NVME_VS(1, 1, 0);
|
||||
/*
|
||||
* The CNS field occupies a full byte starting with NVMe 1.2
|
||||
*/
|
||||
if (ctrl->vs >= NVME_VS(1, 2, 0))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* NVMe 1.1 expanded the CNS value to two bits, which means values
|
||||
* larger than that could get truncated and treated as an incorrect
|
||||
* value.
|
||||
*
|
||||
* Qemu implemented 1.0 behavior for controllers claiming 1.1
|
||||
* compliance, so they need to be quirked here.
|
||||
*/
|
||||
if (ctrl->vs >= NVME_VS(1, 1, 0) &&
|
||||
!(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS))
|
||||
return cns <= 3;
|
||||
|
||||
/*
|
||||
* NVMe 1.0 used a single bit for the CNS value.
|
||||
*/
|
||||
return cns <= 1;
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
if (head->pi_size && head->ms >= head->pi_size)
|
||||
head->pi_type = id->dps & NVME_NS_DPS_PI_MASK;
|
||||
if (!(id->dps & NVME_NS_DPS_PI_FIRST))
|
||||
info->pi_offset = head->ms - head->pi_size;
|
||||
if (!(id->dps & NVME_NS_DPS_PI_FIRST)) {
|
||||
if (disable_pi_offsets)
|
||||
head->pi_type = 0;
|
||||
else
|
||||
info->pi_offset = head->ms - head->pi_size;
|
||||
}
|
||||
|
||||
if (ctrl->ops->flags & NVME_F_FABRICS) {
|
||||
/*
|
||||
@ -3104,7 +3132,7 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl)
|
||||
ctrl->max_zeroes_sectors = 0;
|
||||
|
||||
if (ctrl->subsys->subtype != NVME_NQN_NVME ||
|
||||
nvme_ctrl_limited_cns(ctrl) ||
|
||||
!nvme_id_cns_ok(ctrl, NVME_ID_CNS_CS_CTRL) ||
|
||||
test_bit(NVME_CTRL_SKIP_ID_CNS_CS, &ctrl->flags))
|
||||
return 0;
|
||||
|
||||
@ -4200,7 +4228,7 @@ static void nvme_scan_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
mutex_lock(&ctrl->scan_lock);
|
||||
if (nvme_ctrl_limited_cns(ctrl)) {
|
||||
if (!nvme_id_cns_ok(ctrl, NVME_ID_CNS_NS_ACTIVE_LIST)) {
|
||||
nvme_scan_ns_sequential(ctrl);
|
||||
} else {
|
||||
/*
|
||||
|
@ -421,10 +421,13 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
|
||||
struct io_uring_cmd *ioucmd = req->end_io_data;
|
||||
struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
|
||||
|
||||
if (nvme_req(req)->flags & NVME_REQ_CANCELLED)
|
||||
if (nvme_req(req)->flags & NVME_REQ_CANCELLED) {
|
||||
pdu->status = -EINTR;
|
||||
else
|
||||
} else {
|
||||
pdu->status = nvme_req(req)->status;
|
||||
if (!pdu->status)
|
||||
pdu->status = blk_status_to_errno(err);
|
||||
}
|
||||
pdu->result = le64_to_cpu(nvme_req(req)->result.u64);
|
||||
|
||||
/*
|
||||
|
@ -115,6 +115,7 @@ int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id)
|
||||
pr_debug("%s: ctrl %d failed to generate private key, err %d\n",
|
||||
__func__, ctrl->cntlid, ret);
|
||||
kfree_sensitive(ctrl->dh_key);
|
||||
ctrl->dh_key = NULL;
|
||||
return ret;
|
||||
}
|
||||
ctrl->dh_keysize = crypto_kpp_maxsize(ctrl->dh_tfm);
|
||||
|
Loading…
Reference in New Issue
Block a user