summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGuixin Liu <kanie@linux.alibaba.com>2026-08-04 10:19:01 +0800
committerKeith Busch <kbusch@kernel.org>2026-08-10 17:02:47 -0700
commit53cdaeab2e30e0cb849a74b94f93729ad98946b1 (patch)
treed3383b302ab95344f131d20eab07c964a759e6e0 /drivers
parentcb144c2f67128abfa5c7ba33318617d19f192156 (diff)
downloadlinux-next-53cdaeab2e30e0cb849a74b94f93729ad98946b1.tar.gz
linux-next-53cdaeab2e30e0cb849a74b94f93729ad98946b1.zip
nvme: raise FDP placement handle cap to U8_MAX and warn on overflow
The RUH status buffer and the placement-handle clamp used S8_MAX - 1 (126) as the maximum descriptor count. That value was picked only so the io-mgmt-receive result fit in a page, not because of any protocol or driver restriction. The meaningful upper bound is U8_MAX: write hints (bio->bi_write_stream) are u8, so placement handles beyond U8_MAX can never be selected. Size the buffer and clamp nr_plids to U8_MAX. Suggested-by: Kanchan Joshi <joshi.k@samsung.com> Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Kanchan Joshi <joshi.k@samsung.com> Reviewed-by: Nilay Shroff <nilay@linux.ibm.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Keith Busch <kbusch@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/nvme/host/core.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 975181a74fae..a59abd770aff 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -33,6 +33,13 @@
#define NVME_MINORS (1U << MINORBITS)
+/*
+ * Write hints (bio->bi_write_stream) are u8, so FDP placement handles beyond
+ * U8_MAX can never be selected. Cap the handle count to bound both the RUH
+ * status buffer and the per-head plids array.
+ */
+#define NVME_MAX_PLIDS U8_MAX
+
struct nvme_ns_info {
struct nvme_ns_ids ids;
u32 nsid;
@@ -2353,7 +2360,7 @@ static int nvme_query_fdp_info(struct nvme_ns *ns, struct nvme_ns_info *info)
if (!info->runs)
return ret;
- size = struct_size(ruhs, ruhsd, S8_MAX - 1);
+ size = struct_size(ruhs, ruhsd, NVME_MAX_PLIDS);
ruhs = kzalloc(size, GFP_KERNEL);
if (!ruhs)
return -ENOMEM;
@@ -2368,7 +2375,7 @@ static int nvme_query_fdp_info(struct nvme_ns *ns, struct nvme_ns_info *info)
goto free;
}
- head->nr_plids = min(le16_to_cpu(ruhs->nruhsd), S8_MAX - 1);
+ head->nr_plids = min(le16_to_cpu(ruhs->nruhsd), NVME_MAX_PLIDS);
if (!head->nr_plids)
goto free;