Hi, > On Apr 25, 2025, at 2:02 PM, Jason Andryuk <jason.andr...@amd.com> wrote: > > On 2025-04-25 12:51, Ariadne Conill wrote: >> Previously Xen placed the hypercall page at the highest possible MFN, >> but this caused problems on systems where there is more than 36 bits >> of physical address space. >> In general, it also seems unreliable to assume that the highest possible >> MFN is not already reserved for some other purpose. >> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page") >> Cc: Alejandro Vallejo <agarc...@amd.com> >> Cc: Alexander M. Merritt <alexan...@edera.dev> >> Signed-off-by: Ariadne Conill <ariadne@ariadne.space> >> --- >> xen/arch/x86/guest/hyperv/hyperv.c | 39 ++++++++++--------- >> xen/arch/x86/include/asm/fixmap.h | 3 -- >> xen/arch/x86/include/asm/guest/hyperv-hcall.h | 12 +++--- >> xen/arch/x86/include/asm/guest/hyperv-tlfs.h | 2 + >> xen/arch/x86/include/asm/guest/hyperv.h | 3 -- >> xen/arch/x86/xen.lds.S | 4 -- >> 6 files changed, 28 insertions(+), 35 deletions(-) >> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c >> b/xen/arch/x86/guest/hyperv/hyperv.c >> index 6989af38f1..637b4bf335 100644 >> --- a/xen/arch/x86/guest/hyperv/hyperv.c >> +++ b/xen/arch/x86/guest/hyperv/hyperv.c > >> @@ -98,10 +97,22 @@ static void __init setup_hypercall_page(void) >> rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); >> if ( !hypercall_msr.enable ) >> { >> - mfn = HV_HCALL_MFN; >> + hv_hcall_page = alloc_xenheap_page(); >> + if ( !hv_hcall_page ) >> + { >> + printk("Hyper-V: Failed to allocate hypercall trampoline >> page\n"); > > Minor, but maybe panic() here and avoid changing the return type?
Sure, can do that. > >> + return -ENOMEM; >> + } >> + >> + printk("Hyper-V: Allocated hypercall page @ %p.\n", hv_hcall_page); >> + >> + mfn = virt_to_mfn(hv_hcall_page); >> hypercall_msr.enable = 1; >> hypercall_msr.guest_physical_address = mfn; >> wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); >> + >> + start = (unsigned long) hv_hcall_page; >> + modify_xen_mappings(start, start + PAGE_SIZE, PAGE_HYPERVISOR_RX); >> } >> else >> mfn = hypercall_msr.guest_physical_address; > >> diff --git a/xen/arch/x86/include/asm/guest/hyperv-hcall.h >> b/xen/arch/x86/include/asm/guest/hyperv-hcall.h >> index b76dbf9ccc..b73edca7c6 100644 >> --- a/xen/arch/x86/include/asm/guest/hyperv-hcall.h >> +++ b/xen/arch/x86/include/asm/guest/hyperv-hcall.h >> @@ -20,13 +20,13 @@ static inline uint64_t hv_do_hypercall(uint64_t control, >> paddr_t input_addr, >> paddr_t output_addr) >> { >> uint64_t status; >> - register unsigned long r8 asm ( "r8" ) = output_addr; >> /* See TLFS for volatile registers */ >> - asm volatile ( "call hv_hcall_page" >> + asm volatile ( "mov %[output_addr], %%r8\n" > > Don't you need to list r8 as clobbered? Or maybe just retain the r8 handling > above and below to avoid this mov. This can probably mostly be reverted if we get the fixmap working. The issue we were facing before was a situation where calling hv_hcall_page directly resulted in a page fault due to NX-bit being set on the page. >> + "call *%[target_addr]" > > It might be preferable to retain a direct call which can still be installed > with __set_fixmap_x. Otherwise, __set_fixmap_x can be removed I think we should use fixmap, I just need to figure out what that looks like. Will send v2 patch on Monday. Ariadne