On Wed, Dec 18, 2024 at 12:54:21PM -0800, Roman Kisel wrote: > The Top-Level Functional Specification for Hyper-V, Section 3.6 [1, 2], disallows > overlapping of the input and output hypercall areas, and get_vtl(void) does > overlap them. > > To fix this, enable allocation of the output hypercall pages when running in > the VTL mode and use the output hypercall page of the current vCPU for the > hypercall. > > [1] https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/hypercall-interface > [2] https://github.com/MicrosoftDocs/Virtualization-Documentation/tree/main/tlfs > > Fixes: 8387ce06d70b ("x86/hyperv: Set Virtual Trust Level in VMBus init message") > Signed-off-by: Roman Kisel <romank@xxxxxxxxxxxxxxxxxxx> > --- > arch/x86/hyperv/hv_init.c | 2 +- > drivers/hv/hv_common.c | 6 +++--- > 2 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c > index c7185c6a290b..90c9ea00273e 100644 > --- a/arch/x86/hyperv/hv_init.c > +++ b/arch/x86/hyperv/hv_init.c > @@ -422,7 +422,7 @@ static u8 __init get_vtl(void) > > local_irq_save(flags); > input = *this_cpu_ptr(hyperv_pcpu_input_arg); > - output = (struct hv_get_vp_registers_output *)input; > + output = *this_cpu_ptr(hyperv_pcpu_output_arg); You can do output = (char *)input + HV_HYP_PAGE_SIZE / 2; to avoid the extra allocation. The input and output structures surely won't take up half of the page. Thanks, Wei. > > memset(input, 0, struct_size(input, names, 1)); > input->partition_id = HV_PARTITION_ID_SELF; > diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c > index c4fd07d9bf1a..5178beed6ca8 100644 > --- a/drivers/hv/hv_common.c > +++ b/drivers/hv/hv_common.c > @@ -340,7 +340,7 @@ int __init hv_common_init(void) > BUG_ON(!hyperv_pcpu_input_arg); > > /* Allocate the per-CPU state for output arg for root */ > - if (hv_root_partition) { > + if (hv_root_partition || IS_ENABLED(CONFIG_HYPERV_VTL_MODE)) { > hyperv_pcpu_output_arg = alloc_percpu(void *); > BUG_ON(!hyperv_pcpu_output_arg); > } > @@ -435,7 +435,7 @@ int hv_common_cpu_init(unsigned int cpu) > void **inputarg, **outputarg; > u64 msr_vp_index; > gfp_t flags; > - int pgcount = hv_root_partition ? 2 : 1; > + const int pgcount = (hv_root_partition || IS_ENABLED(CONFIG_HYPERV_VTL_MODE)) ? 2 : 1; > void *mem; > int ret; > > @@ -453,7 +453,7 @@ int hv_common_cpu_init(unsigned int cpu) > if (!mem) > return -ENOMEM; > > - if (hv_root_partition) { > + if (hv_root_partition || IS_ENABLED(CONFIG_HYPERV_VTL_MODE)) { > outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg); > *outputarg = (char *)mem + HV_HYP_PAGE_SIZE; > } > -- > 2.34.1 >