From: Stanislav Kinsburskii <[email protected]> Sent: Thursday, 
May 7, 2026 8:43 AM
> 
> The bounds check inside the PFN-filling loop can return -EINVAL while
> interrupts are disabled via local_irq_save(), leaking IRQ state.
> 
> Remove the check — it is redundant because the loop invariant
> (done + i < page_count == page_struct_count >> large_shift) guarantees
> (done + i) << large_shift < page_struct_count always holds.
> 
> While here, fix type mismatches: change 'int done' to 'u64 done' and
> use u64 for loop and batch-size variables so they match the u64
> page_count they are compared against.
> 
> Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose 
> /dev/mshv to VMMs")
> Signed-off-by: Stanislav Kinsburskii <[email protected]>
> ---
>  drivers/hv/mshv_root_hv_call.c |   18 ++++++------------
>  1 file changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
> index 129456bd72aba..cc580225e9e45 100644
> --- a/drivers/hv/mshv_root_hv_call.c
> +++ b/drivers/hv/mshv_root_hv_call.c
> @@ -1042,7 +1042,7 @@ int hv_call_modify_spa_host_access(u64 partition_id, 
> struct page **pages,
>  {
>       struct hv_input_modify_sparse_spa_page_host_access *input_page;
>       u64 status;
> -     int done = 0;
> +     u64 done = 0;
>       unsigned long irq_flags, large_shift = 0;
>       u64 page_count = page_struct_count;
>       u16 code = acquire ? HVCALL_ACQUIRE_SPARSE_SPA_PAGE_HOST_ACCESS :
> @@ -1059,9 +1059,9 @@ int hv_call_modify_spa_host_access(u64 partition_id, 
> struct page **pages,
>       }
> 
>       while (done < page_count) {
> -             ulong i, completed, remain = page_count - done;
> -             int rep_count = min(remain,
> -                                     
> HV_MODIFY_SPARSE_SPA_PAGE_HOST_ACCESS_MAX_PAGE_COUNT);
> +             u64 i, completed, remain = page_count - done;
> +             u64 rep_count = min_t(u64, remain,
> +                                     
> HV_MODIFY_SPARSE_SPA_PAGE_HOST_ACCESS_MAX_PAGE_COUNT);

Why does this need to be "min_t()" instead of just "min()"?  Needing min_t()
was the case in times past, but "min()" does a much better job now of handling
mixed integer types. There are a number of patches on LKML that are
replacing min_t() with min(). This change seems to be going the opposite
direction.

> 
>               local_irq_save(irq_flags);
>               input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
> @@ -1075,15 +1075,9 @@ int hv_call_modify_spa_host_access(u64 partition_id, 
> struct page **pages,
>               input_page->flags = flags;
>               input_page->host_access = host_access;
> 
> -             for (i = 0; i < rep_count; i++) {
> -                     u64 index = (done + i) << large_shift;
> -
> -                     if (index >= page_struct_count)
> -                             return -EINVAL;
> -
> +             for (i = 0; i < rep_count; i++)
>                       input_page->spa_page_list[i] =
> -                                             page_to_pfn(pages[index]);
> -             }
> +                             page_to_pfn(pages[(done + i) << large_shift]);
> 
>               status = hv_do_rep_hypercall(code, rep_count, 0, input_page,
>                                            NULL);
> 
The "completed" local variable could be collapsed out by doing:

                done += hv_repcomp(status)

Reply via email to