[RFC v1 4/5] hyperv: allow hypercall output pages to be allocated for child partitions

Yu Zhang
2025-12-09T05:11:55Z

Previously, the allocation of per-CPU output argument pages was restricted
to root partitions or those operating in VTL mode.

Remove this restriction to support guest IOMMU related hypercalls, which
require valid output pages to function correctly.

While unconditionally allocating per-CPU output pages scales with the number
of vCPUs, and potentially adding overhead for guests that may not utilize the
IOMMU, this change anticipates that future hypercalls from child partitions
may also require these output pages.

Signed-off-by: Yu Zhang <zhangyu1@linux.microsoft.com>
---
drivers/hv/hv_common.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index e109a620c83f..034fb2592884 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -255,11 +255,6 @@ static void hv_kmsg_dump_register(void)
}
}

-static inline bool hv_output_page_exists(void)
-{
- return hv_parent_partition() || IS_ENABLED(CONFIG_HYPERV_VTL_MODE);
-}
-
void __init hv_get_partition_id(void)
{
struct hv_output_get_partition_id *output;
@@ -371,11 +366,9 @@ int __init hv_common_init(void)
hyperv_pcpu_input_arg = alloc_percpu(void *);
BUG_ON(!hyperv_pcpu_input_arg);

- /* Allocate the per-CPU state for output arg for root */
- if (hv_output_page_exists()) {
- hyperv_pcpu_output_arg = alloc_percpu(void *);
- BUG_ON(!hyperv_pcpu_output_arg);
- }
+ /* Allocate the per-CPU state for output arg*/
+ hyperv_pcpu_output_arg = alloc_percpu(void *);
+ BUG_ON(!hyperv_pcpu_output_arg);

if (hv_parent_partition()) {
hv_synic_eventring_tail = alloc_percpu(u8 *);
@@ -473,7 +466,7 @@ int hv_common_cpu_init(unsigned int cpu)
u8 **synic_eventring_tail;
u64 msr_vp_index;
gfp_t flags;
- const int pgcount = hv_output_page_exists() ? 2 : 1;
+ const int pgcount = 2;
void *mem;
int ret = 0;

@@ -491,10 +484,8 @@ int hv_common_cpu_init(unsigned int cpu)
if (!mem)
return -ENOMEM;

- if (hv_output_page_exists()) {
- outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
- *outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
- }
+ outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
+ *outputarg = (char *)mem + HV_HYP_PAGE_SIZE;

if (!ms_hyperv.paravisor_present &&
(hv_isolation_type_snp() || hv_isolation_type_tdx())) {
--
2.49.0