[PATCH] scsi: sd_zbc: Limit the report zones buffer size to UIO_MAXIOV

Steve Siwinski posted 1 patch 10 months ago
drivers/scsi/sd_zbc.c | 3 +++
1 file changed, 3 insertions(+)
[PATCH] scsi: sd_zbc: Limit the report zones buffer size to UIO_MAXIOV
Posted by Steve Siwinski 10 months ago
The report zones buffer size is currently limited by the HBA's
maximum segment count to ensure the buffer can be mapped. However,
the user-space SG_IO interface further limits the number of iovec
entries to UIO_MAXIOV when allocating a bio.

To avoid allocation of buffers too large to be mapped, further
restrict the maximum buffer size to UIO_MAXIOV * PAGE_SIZE.

This ensures that the buffer size complies with both kernel
and user-space constraints.

Signed-off-by: Steve Siwinski <ssiwinski@atto.com>
---
 drivers/scsi/sd_zbc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index 7a447ff600d2..a19e76ec8fb6 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -180,12 +180,15 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
 	 * Furthermore, since the report zone command cannot be split, make
 	 * sure that the allocated buffer can always be mapped by limiting the
 	 * number of pages allocated to the HBA max segments limit.
+	 * Since max segments can be larger than the max sgio entries, further
+	 * limit the allocated buffer to the UIO_MAXIOV.
 	 */
 	nr_zones = min(nr_zones, sdkp->zone_info.nr_zones);
 	bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE);
 	bufsize = min_t(size_t, bufsize,
 			queue_max_hw_sectors(q) << SECTOR_SHIFT);
 	bufsize = min_t(size_t, bufsize, queue_max_segments(q) << PAGE_SHIFT);
+	bufsize = min_t(size_t, bufsize, UIO_MAXIOV * PAGE_SIZE);
 
 	while (bufsize >= SECTOR_SIZE) {
 		buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY);
-- 
2.43.5
Re: [PATCH] scsi: sd_zbc: Limit the report zones buffer size to UIO_MAXIOV
Posted by Christoph Hellwig 9 months, 4 weeks ago
On Fri, Apr 11, 2025 at 04:36:00PM -0400, Steve Siwinski wrote:
> The report zones buffer size is currently limited by the HBA's
> maximum segment count to ensure the buffer can be mapped. However,
> the user-space SG_IO interface further limits the number of iovec
> entries to UIO_MAXIOV when allocating a bio.

Why does the userspace SG_IO interface matter here?
sd_zbc_alloc_report_buffer is only used for the in-kernel
->report_zones call.

> 
> To avoid allocation of buffers too large to be mapped, further
> restrict the maximum buffer size to UIO_MAXIOV * PAGE_SIZE.
> 
> This ensures that the buffer size complies with both kernel
> and user-space constraints.
> 
> Signed-off-by: Steve Siwinski <ssiwinski@atto.com>
> ---
>  drivers/scsi/sd_zbc.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
> index 7a447ff600d2..a19e76ec8fb6 100644
> --- a/drivers/scsi/sd_zbc.c
> +++ b/drivers/scsi/sd_zbc.c
> @@ -180,12 +180,15 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
>  	 * Furthermore, since the report zone command cannot be split, make
>  	 * sure that the allocated buffer can always be mapped by limiting the
>  	 * number of pages allocated to the HBA max segments limit.
> +	 * Since max segments can be larger than the max sgio entries, further
> +	 * limit the allocated buffer to the UIO_MAXIOV.
>  	 */
>  	nr_zones = min(nr_zones, sdkp->zone_info.nr_zones);
>  	bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE);
>  	bufsize = min_t(size_t, bufsize,
>  			queue_max_hw_sectors(q) << SECTOR_SHIFT);
>  	bufsize = min_t(size_t, bufsize, queue_max_segments(q) << PAGE_SHIFT);
> +	bufsize = min_t(size_t, bufsize, UIO_MAXIOV * PAGE_SIZE);
>  
>  	while (bufsize >= SECTOR_SIZE) {
>  		buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY);
> -- 
> 2.43.5
> 
> 
---end quoted text---