From: [email protected] <[email protected]> Sent: Monday, May 5, 
2025 5:57 PM
> 
> There are use cases that interrupt and monitor pages are mapped to
> user-mode through UIO, so they need to be system page aligned. Some
> Hyper-V allocation APIs introduced earlier broke those requirements.
> 
> Fix this by using page allocation functions directly for interrupt
> and monitor pages.
> 
> Cc: [email protected]
> Fixes: ca48739e59df ("Drivers: hv: vmbus: Move Hyper-V page allocator to arch 
> neutral code")
> Signed-off-by: Long Li <[email protected]>
> ---
>  drivers/hv/connection.c | 23 +++++++++++++++++------
>  1 file changed, 17 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
> index 8351360bba16..be490c598785 100644
> --- a/drivers/hv/connection.c
> +++ b/drivers/hv/connection.c
> @@ -206,11 +206,20 @@ int vmbus_connect(void)
>       INIT_LIST_HEAD(&vmbus_connection.chn_list);
>       mutex_init(&vmbus_connection.channel_mutex);
> 
> +     /*
> +      * The following Hyper-V interrupt and monitor pages can be used by
> +      * UIO for mapping to user-space, so they should always be allocated on
> +      * system page boundaries. The system page size must be >= the Hyper-V
> +      * page size.
> +      */
> +     BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
> +
>       /*
>        * Setup the vmbus event connection for channel interrupt
>        * abstraction stuff
>        */
> -     vmbus_connection.int_page = hv_alloc_hyperv_zeroed_page();
> +     vmbus_connection.int_page =
> +             (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
>       if (vmbus_connection.int_page == NULL) {
>               ret = -ENOMEM;
>               goto cleanup;
> @@ -225,8 +234,8 @@ int vmbus_connect(void)
>        * Setup the monitor notification facility. The 1st page for
>        * parent->child and the 2nd page for child->parent
>        */
> -     vmbus_connection.monitor_pages[0] = hv_alloc_hyperv_page();
> -     vmbus_connection.monitor_pages[1] = hv_alloc_hyperv_page();
> +     vmbus_connection.monitor_pages[0] = (void *)__get_free_page(GFP_KERNEL);
> +     vmbus_connection.monitor_pages[1] = (void *)__get_free_page(GFP_KERNEL);
>       if ((vmbus_connection.monitor_pages[0] == NULL) ||
>           (vmbus_connection.monitor_pages[1] == NULL)) {
>               ret = -ENOMEM;
> @@ -342,21 +351,23 @@ void vmbus_disconnect(void)
>               destroy_workqueue(vmbus_connection.work_queue);
> 
>       if (vmbus_connection.int_page) {
> -             hv_free_hyperv_page(vmbus_connection.int_page);
> +             free_page((unsigned long)vmbus_connection.int_page);
>               vmbus_connection.int_page = NULL;
>       }
> 
>       if (vmbus_connection.monitor_pages[0]) {
>               if (!set_memory_encrypted(
>                       (unsigned long)vmbus_connection.monitor_pages[0], 1))
> -                     hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
> +                     free_page((unsigned long)
> +                             vmbus_connection.monitor_pages[0]);
>               vmbus_connection.monitor_pages[0] = NULL;
>       }
> 
>       if (vmbus_connection.monitor_pages[1]) {
>               if (!set_memory_encrypted(
>                       (unsigned long)vmbus_connection.monitor_pages[1], 1))
> -                     hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
> +                     free_page((unsigned long)
> +                             vmbus_connection.monitor_pages[1]);
>               vmbus_connection.monitor_pages[1] = NULL;
>       }
>  }
> --
> 2.34.1
> 

Reviewed-by: Michael Kelley <[email protected]>

Reply via email to