On Thu, May 07, 2026 at 03:43:59PM +0000, Stanislav Kinsburskii wrote:
> idr_alloc() is called with GFP_KERNEL inside idr_lock(), which holds a
> spinlock. GFP_KERNEL allows the allocator to sleep, triggering a
> sleeping-while-atomic bug.
> 
> Fix by using idr_preload(GFP_KERNEL) before taking the lock to
> pre-allocate memory in a sleepable context, then idr_alloc() with
> GFP_NOWAIT inside the spinlock-protected section.
> 
> Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose 
> /dev/mshv to VMMs")
> Signed-off-by: Stanislav Kinsburskii <[email protected]>
> ---
>  drivers/hv/mshv_portid_table.c |    6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hv/mshv_portid_table.c b/drivers/hv/mshv_portid_table.c
> index 4cdf8e9575390..d87a82e399e96 100644
> --- a/drivers/hv/mshv_portid_table.c
> +++ b/drivers/hv/mshv_portid_table.c
> @@ -40,12 +40,14 @@ mshv_port_table_fini(void)
>  int
>  mshv_portid_alloc(struct port_table_info *info)
>  {
> -     int ret = 0;
> +     int ret;
>  
> +     idr_preload(GFP_KERNEL);
>       idr_lock(&port_table_idr);
>       ret = idr_alloc(&port_table_idr, info, PORTID_MIN,
> -                     PORTID_MAX, GFP_KERNEL);
> +                     PORTID_MAX, GFP_NOWAIT);
>       idr_unlock(&port_table_idr);
> +     idr_preload_end();
>  
>       return ret;
>  }
> 
> 

Reviewed-by: Anirudh Rayabharam (Microsoft) <[email protected]>


Reply via email to