Skip to contentSkip to conversation

Fix uio_hv_generic on systems with >4k page sizes

PATCH Superseded [email protected] 3 participants 10 messages Apr 30, 2025 – May 6, 2025

Subsystems (5)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover Fix uio_hv_generic on systems with >4k page sizes

From: Long Li <[email protected]>

UIO framework requires the device memory aligned to page boundary. Hyper-V may allocate some memory that is Hyper-V page aligned (4k) but not system page aligned.

Fix this by having Hyper-V always allocate those pages on system page boundary and expose them to user-mode.

Change in v2:
Added two more patches to the series:
"uio_hv_generic: Adjust ring size according to system page alignment" "Drivers: hv: Remove hv_free/alloc_* helpers"

Added more details in the commit message of "uio_hv_generic: Use correct size for interrupt and monitor pages"

Long Li (4):
Drivers: hv: Allocate interrupt and monitor pages aligned to system
page boundary
uio_hv_generic: Use correct size for interrupt and monitor pages
uio_hv_generic: Adjust ring size according to system page alignment
Drivers: hv: Remove hv_free/alloc_* helpers

 drivers/hv/connection.c        | 21 +++++++++++-----
 drivers/hv/hv_common.c         | 45 +++-------------------------------
 drivers/uio/uio_hv_generic.c   |  7 ++++--
 include/asm-generic/mshyperv.h |  4 ---
 4 files changed, 23 insertions(+), 54 deletions(-)
Signature · 1 line
2.34.1
#1 lore raw

PATCH v2 1/4 Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary

From: Long Li <[email protected]>

There are use cases that interrupt and monitor pages are mapped to user-mode through UIO, they need to be system page aligned. Some Hyper-V allocation APIs introduced earlier broke those requirements.

Fix those APIs by always allocating Hyper-V page at system page boundaries.

Fixes ca48739e59df ("Drivers: hv: vmbus: Move Hyper-V page allocator to arch neutral code")
---
 drivers/hv/hv_common.c | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)
drivers/hv/hv_common.c +10 -25
index a7d7494feaca..297ccd7d4997 100644
@@ -106,41 +106,26 @@ void __init hv_common_free(void)
 }
 
 /*
- * Functions for allocating and freeing memory with size and
- * alignment HV_HYP_PAGE_SIZE. These functions are needed because
- * the guest page size may not be the same as the Hyper-V page
- * size. We depend upon kmalloc() aligning power-of-two size
- * allocations to the allocation size boundary, so that the
- * allocated memory appears to Hyper-V as a page of the size
- * it expects.
+ * A Hyper-V page can be used by UIO for mapping to user-space, it should
+ * always be allocated on system page boundaries.
  */
-
 void *hv_alloc_hyperv_page(void)
 {
-	BUILD_BUG_ON(PAGE_SIZE <  HV_HYP_PAGE_SIZE);
-
-	if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
-		return (void *)__get_free_page(GFP_KERNEL);
-	else
-		return kmalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
+	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
+	return (void *)__get_free_page(GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(hv_alloc_hyperv_page);
 
 void *hv_alloc_hyperv_zeroed_page(void)
 {
-	if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
-		return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-	else
-		return kzalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
+	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
+	return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
 }
 EXPORT_SYMBOL_GPL(hv_alloc_hyperv_zeroed_page);
 
 void hv_free_hyperv_page(void *addr)
 {
-	if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
-		free_page((unsigned long)addr);
-	else
-		kfree(addr);
+	free_page((unsigned long)addr);
 }
 EXPORT_SYMBOL_GPL(hv_free_hyperv_page);
 
@@ -272,7 +257,7 @@ static void hv_kmsg_dump_unregister(void)
 	atomic_notifier_chain_unregister(&panic_notifier_list,
 					 &hyperv_panic_report_block);
 
-	hv_free_hyperv_page(hv_panic_page);
+	kfree(hv_panic_page);
 	hv_panic_page = NULL;
 }
 
@@ -280,7 +265,7 @@ static void hv_kmsg_dump_register(void)
 {
 	int ret;
 
-	hv_panic_page = hv_alloc_hyperv_zeroed_page();
+	hv_panic_page = kzalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
 	if (!hv_panic_page) {
 		pr_err("Hyper-V: panic message page memory allocation failed\n");
 		return;
@@ -289,7 +274,7 @@ static void hv_kmsg_dump_register(void)
 	ret = kmsg_dump_register(&hv_kmsg_dumper);
 	if (ret) {
 		pr_err("Hyper-V: kmsg dump register error 0x%x\n", ret);
-		hv_free_hyperv_page(hv_panic_page);
+		kfree(hv_panic_page);
 		hv_panic_page = NULL;
 	}
 }
Signature · 1 line
2.34.1
#2 lore raw

RE: [Patch v2 1/4] Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary

From: [email protected] <[email protected]> Sent: Wednesday, April 30, 2025 3:06 PM

Quoted 3 lines

There are use cases that interrupt and monitor pages are mapped to user-mode through UIO, they need to be system page aligned. Some Hyper-V

s/UIO, they/UIO, so they/

Quoted 3 lines

allocation APIs introduced earlier broke those requirements.

Fix those APIs by always allocating Hyper-V page at system page boundaries.

This patch modifies hv_alloc_hyperv_page() and friends. Then Patch 4 of the series deletes them, including the modifications. It would be less code motion to do the first part of Patch 4 (i.e., the use of __get_free_page directly in connection.c) here in Patch 1, and leave hv_alloc_hyperv_page() and friends unmodified. Continue to make the change to hv_kmsg_dump_register() here in Patch 1 as well.

Then have Patch 2 simply delete hv_alloc_hyperv_page() and friends because they are no longer used. The modifications to hv_alloc_hyperv_page() and friends would not be needed.

Patch 3 and 4 would be the additional changes in uio_hv_generic.c.

Michael

Quoted 91 lines
Fixes ca48739e59df ("Drivers: hv: vmbus: Move Hyper-V page allocator to arch neutral code")
---
 drivers/hv/hv_common.c | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)
drivers/hv/hv_common.c +10 -26
index a7d7494feaca..297ccd7d4997 100644
@@ -106,41 +106,26 @@ void __init hv_common_free(void)
 }
 
 /*
- * Functions for allocating and freeing memory with size and
- * alignment HV_HYP_PAGE_SIZE. These functions are needed because
- * the guest page size may not be the same as the Hyper-V page
- * size. We depend upon kmalloc() aligning power-of-two size
- * allocations to the allocation size boundary, so that the
- * allocated memory appears to Hyper-V as a page of the size
- * it expects.
+ * A Hyper-V page can be used by UIO for mapping to user-space, it should
+ * always be allocated on system page boundaries.
  */
-
 void *hv_alloc_hyperv_page(void)
 {
-	BUILD_BUG_ON(PAGE_SIZE <  HV_HYP_PAGE_SIZE);
-
-	if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
-		return (void *)__get_free_page(GFP_KERNEL);
-	else
-		return kmalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
+	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
+	return (void *)__get_free_page(GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(hv_alloc_hyperv_page);
 
 void *hv_alloc_hyperv_zeroed_page(void)
 {
-	if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
-		return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-	else
-		return kzalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
+	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
+	return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
 }
 EXPORT_SYMBOL_GPL(hv_alloc_hyperv_zeroed_page);
 
 void hv_free_hyperv_page(void *addr)
 {
-	if (PAGE_SIZE == HV_HYP_PAGE_SIZE)
-		free_page((unsigned long)addr);
-	else
-		kfree(addr);
+	free_page((unsigned long)addr);
 }
 EXPORT_SYMBOL_GPL(hv_free_hyperv_page);
 
@@ -272,7 +257,7 @@ static void hv_kmsg_dump_unregister(void)
 	atomic_notifier_chain_unregister(&panic_notifier_list,
 					 &hyperv_panic_report_block);
 
-	hv_free_hyperv_page(hv_panic_page);
+	kfree(hv_panic_page);
 	hv_panic_page = NULL;
 }
 
@@ -280,7 +265,7 @@ static void hv_kmsg_dump_register(void)
 {
 	int ret;
 
-	hv_panic_page = hv_alloc_hyperv_zeroed_page();
+	hv_panic_page = kzalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
 	if (!hv_panic_page) {
 		pr_err("Hyper-V: panic message page memory allocation failed\n");
 		return;
@@ -289,7 +274,7 @@ static void hv_kmsg_dump_register(void)
 	ret = kmsg_dump_register(&hv_kmsg_dumper);
 	if (ret) {
 		pr_err("Hyper-V: kmsg dump register error 0x%x\n", ret);
-		hv_free_hyperv_page(hv_panic_page);
+		kfree(hv_panic_page);
 		hv_panic_page = NULL;
 	}
 }
--

2.34.1

#3 lore raw

RE: [Patch v2 1/4] Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary

Quoted 34 lines

-----Original Message-----
From: Michael Kelley <[email protected]>
Sent: Wednesday, April 30, 2025 6:56 PM
To: [email protected]; KY Srinivasan <[email protected]>; Haiyang Zhang <[email protected]>; Wei Liu <[email protected]>; Dexuan Cui <[email protected]>; Greg Kroah-Hartman <[email protected]>; [email protected]; linux- [email protected]
Cc: Long Li <[email protected]>; [email protected]
Subject: [EXTERNAL] RE: [Patch v2 1/4] Drivers: hv: Allocate interrupt and monitor pages aligned to system page boundary

From: [email protected] <[email protected]> Sent:
Wednesday, April 30, 2025 3:06 PM

Quoted 4 lines

There are use cases that interrupt and monitor pages are mapped to user-mode through UIO, they need to be system page aligned. Some Hyper-V

s/UIO, they/UIO, so they/

Quoted 3 lines

allocation APIs introduced earlier broke those requirements.

Fix those APIs by always allocating Hyper-V page at system page boundaries.

This patch modifies hv_alloc_hyperv_page() and friends. Then Patch 4 of the series deletes them, including the modifications. It would be less code motion to do the first part of Patch 4 (i.e., the use of __get_free_page directly in connection.c) here in Patch 1, and leave hv_alloc_hyperv_page() and friends unmodified. Continue to make the change to hv_kmsg_dump_register() here in Patch 1 as well.

Quoted 7 lines

Then have Patch 2 simply delete hv_alloc_hyperv_page() and friends because they are no longer used. The modifications to hv_alloc_hyperv_page() and friends would not be needed.

Patch 3 and 4 would be the additional changes in uio_hv_generic.c.

Michael

I have sent v3 of the patch series.

Long

#4 lore raw

PATCH v2 2/4 uio_hv_generic: Use correct size for interrupt and monitor pages

In reply to [email protected]

From: Long Li <[email protected]>

Interrupt and monitor pages should be in Hyper-V page size (4k bytes). This can be different to the system page size.

This size is read and used by the user-mode program to determine the mapped data region. An example of such user-mode program is the VMBUS driver in DPDK.

Fixes 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus")
---
 drivers/uio/uio_hv_generic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/uio/uio_hv_generic.c +2 -2
index 1b19b5647495..08385b04c4ab 100644
@@ -287,13 +287,13 @@ hv_uio_probe(struct hv_device *dev,
 	pdata->info.mem[INT_PAGE_MAP].name = "int_page";
 	pdata->info.mem[INT_PAGE_MAP].addr
 		= (uintptr_t)vmbus_connection.int_page;
-	pdata->info.mem[INT_PAGE_MAP].size = PAGE_SIZE;
+	pdata->info.mem[INT_PAGE_MAP].size = HV_HYP_PAGE_SIZE;
 	pdata->info.mem[INT_PAGE_MAP].memtype = UIO_MEM_LOGICAL;
 
 	pdata->info.mem[MON_PAGE_MAP].name = "monitor_page";
 	pdata->info.mem[MON_PAGE_MAP].addr
 		= (uintptr_t)vmbus_connection.monitor_pages[1];
-	pdata->info.mem[MON_PAGE_MAP].size = PAGE_SIZE;
+	pdata->info.mem[MON_PAGE_MAP].size = HV_HYP_PAGE_SIZE;
 	pdata->info.mem[MON_PAGE_MAP].memtype = UIO_MEM_LOGICAL;
 
 	if (channel->device_id == HV_NIC) {
Signature · 1 line
2.34.1
#5 lore raw

RE: [Patch v2 2/4] uio_hv_generic: Use correct size for interrupt and monitor pages

From: [email protected] <[email protected]> Sent: Wednesday, April 30, 2025 3:06 PM

Quoted 3 lines

Interrupt and monitor pages should be in Hyper-V page size (4k bytes). This can be different to the system page size.

s/different to/different from/

Quoted 3 lines

This size is read and used by the user-mode program to determine the mapped data region. An example of such user-mode program is the VMBUS

s/VMBUS/VMBus/

Quoted 32 lines

driver in DPDK.

Fixes 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus")
---
 drivers/uio/uio_hv_generic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/uio/uio_hv_generic.c +2 -3
index 1b19b5647495..08385b04c4ab 100644
@@ -287,13 +287,13 @@ hv_uio_probe(struct hv_device *dev,
 	pdata->info.mem[INT_PAGE_MAP].name = "int_page";
 	pdata->info.mem[INT_PAGE_MAP].addr
 		= (uintptr_t)vmbus_connection.int_page;
-	pdata->info.mem[INT_PAGE_MAP].size = PAGE_SIZE;
+	pdata->info.mem[INT_PAGE_MAP].size = HV_HYP_PAGE_SIZE;
 	pdata->info.mem[INT_PAGE_MAP].memtype = UIO_MEM_LOGICAL;
 
 	pdata->info.mem[MON_PAGE_MAP].name = "monitor_page";
 	pdata->info.mem[MON_PAGE_MAP].addr
 		= (uintptr_t)vmbus_connection.monitor_pages[1];
-	pdata->info.mem[MON_PAGE_MAP].size = PAGE_SIZE;
+	pdata->info.mem[MON_PAGE_MAP].size = HV_HYP_PAGE_SIZE;
 	pdata->info.mem[MON_PAGE_MAP].memtype = UIO_MEM_LOGICAL;
 
 	if (channel->device_id == HV_NIC) {
--

2.34.1

#6 lore raw

PATCH v2 3/4 uio_hv_generic: Adjust ring size according to system page alignment

In reply to [email protected]

From: Long Li <[email protected]>

Following the ring header, the ring data should align to system page boundary. Adjust the size if necessary.

Fixes 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus")
---
 drivers/uio/uio_hv_generic.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/uio/uio_hv_generic.c +6 -0
index 08385b04c4ab..dfc5f0e1a254 100644
@@ -256,6 +256,12 @@ hv_uio_probe(struct hv_device *dev,
 	if (!ring_size)
 		ring_size = SZ_2M;
 
+	/*
+	 * Adjust ring size if necessary to have the ring data region page
+	 * aligned
+	 */
+	ring_size = VMBUS_RING_SIZE(ring_size);
+
 	pdata = devm_kzalloc(&dev->device, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
Signature · 1 line
2.34.1
Reviewed-by on v2 3/4
#7 lore raw

RE: [Patch v2 3/4] uio_hv_generic: Adjust ring size according to system page alignment

From: [email protected] <[email protected]> Sent: Wednesday, April 30, 2025 3:06 PM

Quoted 29 lines

Following the ring header, the ring data should align to system page boundary. Adjust the size if necessary.

Fixes 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus")
---
 drivers/uio/uio_hv_generic.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/uio/uio_hv_generic.c +6 -1
index 08385b04c4ab..dfc5f0e1a254 100644
@@ -256,6 +256,12 @@ hv_uio_probe(struct hv_device *dev,
 	if (!ring_size)
 		ring_size = SZ_2M;
 
+	/*
+	 * Adjust ring size if necessary to have the ring data region page
+	 * aligned
+	 */
+	ring_size = VMBUS_RING_SIZE(ring_size);
+
 	pdata = devm_kzalloc(&dev->device, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
--
Quoted 2 lines

2.34.1

#8 lore raw

PATCH v2 4/4 Drivers: hv: Remove hv_free/alloc_* helpers

In reply to [email protected]

From: Long Li <[email protected]>

Those helpers are simply wrappers for page allocations.

---
 drivers/hv/connection.c        | 23 +++++++++++++++++------
 drivers/hv/hv_common.c         | 24 ------------------------
 include/asm-generic/mshyperv.h |  4 ----
 3 files changed, 17 insertions(+), 34 deletions(-)
drivers/hv/connection.c +17 -6
index 8351360bba16..a0160b73b593 100644
@@ -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, it should always be allocated on
+	 * system page boundaries. We use page allocation functions to allocate
+	 * those pages. We assume system page be bigger than Hyper-v page.
+	 */
+	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;
 	}
 }
drivers/hv/hv_common.c +0 -24
index 297ccd7d4997..421376cea17e 100644
@@ -105,30 +105,6 @@ void __init hv_common_free(void)
 	hv_synic_eventring_tail = NULL;
 }
 
-/*
- * A Hyper-V page can be used by UIO for mapping to user-space, it should
- * always be allocated on system page boundaries.
- */
-void *hv_alloc_hyperv_page(void)
-{
-	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
-	return (void *)__get_free_page(GFP_KERNEL);
-}
-EXPORT_SYMBOL_GPL(hv_alloc_hyperv_page);
-
-void *hv_alloc_hyperv_zeroed_page(void)
-{
-	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
-	return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-}
-EXPORT_SYMBOL_GPL(hv_alloc_hyperv_zeroed_page);
-
-void hv_free_hyperv_page(void *addr)
-{
-	free_page((unsigned long)addr);
-}
-EXPORT_SYMBOL_GPL(hv_free_hyperv_page);
-
 static void *hv_panic_page;
 
 /*
include/asm-generic/mshyperv.h +0 -4
index ccccb1cbf7df..4033508fbb11 100644
@@ -236,10 +236,6 @@ int hv_common_cpu_init(unsigned int cpu);
 int hv_common_cpu_die(unsigned int cpu);
 void hv_identify_partition_type(void);
 
-void *hv_alloc_hyperv_page(void);
-void *hv_alloc_hyperv_zeroed_page(void);
-void hv_free_hyperv_page(void *addr);
-
 /**
  * hv_cpu_number_to_vp_number() - Map CPU to VP.
  * @cpu_number: CPU number in Linux terms
Signature · 1 line
2.34.1
#9 lore raw

RE: [Patch v2 4/4] Drivers: hv: Remove hv_free/alloc_* helpers

From: [email protected] <[email protected]> Sent: Wednesday, April 30, 2025 3:06 PM

drivers/hv/connection.c

Quoted 14 lines

Those helpers are simply wrappers for page allocations.

---
 drivers/hv/connection.c        | 23 +++++++++++++++++------
 drivers/hv/hv_common.c         | 24 ------------------------
 include/asm-generic/mshyperv.h |  4 ----
 3 files changed, 17 insertions(+), 34 deletions(-)
drivers/hv/connection.c +0 -0
index 8351360bba16..a0160b73b593 100644

See my comment in Patch 1 of the series, suggesting that these changes to connection.c move into Patch 1.

drivers/hv/connection.c int vmbus_connect(void) · line 211

Quoted 7 lines
drivers/hv/connection.c +3 -0
@@ -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, it should always be allocated on

s/it should/so should/

drivers/hv/connection.c int vmbus_connect(void) · line 213

Quoted 2 lines
drivers/hv/connection.c +2 -0
+	 * system page boundaries. We use page allocation functions to allocate
+	 * those pages. We assume system page be bigger than Hyper-v page.

Instead of your last sentence above, say:

The system page size must be >= the Hyper-V page size.

Quoted 104 lines
drivers/hv/connection.c +12 -6
+	 */
+	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;
 	}
 }
drivers/hv/hv_common.c +0 -24
index 297ccd7d4997..421376cea17e 100644
@@ -105,30 +105,6 @@ void __init hv_common_free(void)
 	hv_synic_eventring_tail = NULL;
 }
 
-/*
- * A Hyper-V page can be used by UIO for mapping to user-space, it should
- * always be allocated on system page boundaries.
- */
-void *hv_alloc_hyperv_page(void)
-{
-	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
-	return (void *)__get_free_page(GFP_KERNEL);
-}
-EXPORT_SYMBOL_GPL(hv_alloc_hyperv_page);
-
-void *hv_alloc_hyperv_zeroed_page(void)
-{
-	BUILD_BUG_ON(PAGE_SIZE < HV_HYP_PAGE_SIZE);
-	return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-}
-EXPORT_SYMBOL_GPL(hv_alloc_hyperv_zeroed_page);
-
-void hv_free_hyperv_page(void *addr)
-{
-	free_page((unsigned long)addr);
-}
-EXPORT_SYMBOL_GPL(hv_free_hyperv_page);
-
 static void *hv_panic_page;
 
 /*
include/asm-generic/mshyperv.h +0 -5
index ccccb1cbf7df..4033508fbb11 100644
@@ -236,10 +236,6 @@ int hv_common_cpu_init(unsigned int cpu);
 int hv_common_cpu_die(unsigned int cpu);
 void hv_identify_partition_type(void);
 
-void *hv_alloc_hyperv_page(void);
-void *hv_alloc_hyperv_zeroed_page(void);
-void hv_free_hyperv_page(void *addr);
-
 /**
  * hv_cpu_number_to_vp_number() - Map CPU to VP.
  * @cpu_number: CPU number in Linux terms
--

2.34.1