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]>