diff options
| author | Guixin Liu <kanie@linux.alibaba.com> | 2026-08-04 10:19:01 +0800 |
|---|---|---|
| committer | Keith Busch <kbusch@kernel.org> | 2026-08-10 17:02:47 -0700 |
| commit | 53cdaeab2e30e0cb849a74b94f93729ad98946b1 (patch) | |
| tree | d3383b302ab95344f131d20eab07c964a759e6e0 /drivers | |
| parent | cb144c2f67128abfa5c7ba33318617d19f192156 (diff) | |
| download | linux-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.c | 11 |
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; |
