All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
@ 2025-04-25 23:43 Ariadne Conill
  2025-04-28  7:00 ` Jan Beulich
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Ariadne Conill @ 2025-04-25 23:43 UTC (permalink / raw)
  To: xen-devel
  Cc: Ariadne Conill, Paul Durrant, Jan Beulich, Andrew Cooper,
	Roger Pau Monné, Alejandro Vallejo, Alexander M . Merritt

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.

Changes from v1:
- Continue to use fixmap infrastructure
- Use panic in Hyper-V setup() function instead of returning -ENOMEM
  on hypercall page allocation failure

Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
Cc: Alejandro Vallejo <agarciav@amd.com>
Cc: Alexander M. Merritt <alexander@edera.dev>
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
---
 xen/arch/x86/guest/hyperv/hyperv.c      | 17 +++++++----------
 xen/arch/x86/include/asm/guest/hyperv.h |  3 ---
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
index 6989af38f1..0305374a06 100644
--- a/xen/arch/x86/guest/hyperv/hyperv.c
+++ b/xen/arch/x86/guest/hyperv/hyperv.c
@@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
     rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
     if ( !hypercall_msr.enable )
     {
-        mfn = HV_HCALL_MFN;
+        void *hcall_page = alloc_xenheap_page();
+        if ( !hcall_page )
+            panic("Hyper-V: Failed to allocate hypercall trampoline page");
+
+        printk("Hyper-V: Allocated hypercall page @ %p.\n", hcall_page);
+
+        mfn = virt_to_mfn(hcall_page);
         hypercall_msr.enable = 1;
         hypercall_msr.guest_physical_address = mfn;
         wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
@@ -187,14 +193,6 @@ static int cf_check ap_setup(void)
     return setup_vp_assist();
 }
 
-static void __init cf_check e820_fixup(void)
-{
-    uint64_t s = HV_HCALL_MFN << PAGE_SHIFT;
-
-    if ( !e820_add_range(s, s + PAGE_SIZE, E820_RESERVED) )
-        panic("Unable to reserve Hyper-V hypercall range\n");
-}
-
 static int cf_check flush_tlb(
     const cpumask_t *mask, const void *va, unsigned int flags)
 {
@@ -211,7 +209,6 @@ static const struct hypervisor_ops __initconst_cf_clobber ops = {
     .name = "Hyper-V",
     .setup = setup,
     .ap_setup = ap_setup,
-    .e820_fixup = e820_fixup,
     .flush_tlb = flush_tlb,
 };
 
diff --git a/xen/arch/x86/include/asm/guest/hyperv.h b/xen/arch/x86/include/asm/guest/hyperv.h
index c05efdce71..5792e77104 100644
--- a/xen/arch/x86/include/asm/guest/hyperv.h
+++ b/xen/arch/x86/include/asm/guest/hyperv.h
@@ -10,9 +10,6 @@
 
 #include <xen/types.h>
 
-/* Use top-most MFN for hypercall page */
-#define HV_HCALL_MFN   (((1ull << paddr_bits) - 1) >> HV_HYP_PAGE_SHIFT)
-
 /*
  * The specification says: "The partition reference time is computed
  * by the following formula:
-- 
2.39.5 (Apple Git-154)



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-25 23:43 [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls Ariadne Conill
@ 2025-04-28  7:00 ` Jan Beulich
  2025-04-28  9:41 ` Roger Pau Monné
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Jan Beulich @ 2025-04-28  7:00 UTC (permalink / raw)
  To: Ariadne Conill
  Cc: Paul Durrant, Andrew Cooper, Roger Pau Monné,
	Alejandro Vallejo, Alexander M . Merritt, xen-devel

On 26.04.2025 01:43, 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.
> 
> Changes from v1:
> - Continue to use fixmap infrastructure
> - Use panic in Hyper-V setup() function instead of returning -ENOMEM
>   on hypercall page allocation failure

Nit: This part wants to go ...

> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
> Cc: Alejandro Vallejo <agarciav@amd.com>
> Cc: Alexander M. Merritt <alexander@edera.dev>
> Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
> ---

... somewhere below such a separator.

> --- a/xen/arch/x86/guest/hyperv/hyperv.c
> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>      if ( !hypercall_msr.enable )
>      {
> -        mfn = HV_HCALL_MFN;
> +        void *hcall_page = alloc_xenheap_page();
> +        if ( !hcall_page )

Nit (style): Blank line please between declaration(s) and statement(s). (Both
can probably be taken care of upon committing if no other need for a v3 arises.)

Jan


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-25 23:43 [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls Ariadne Conill
  2025-04-28  7:00 ` Jan Beulich
@ 2025-04-28  9:41 ` Roger Pau Monné
  2025-04-28 10:55   ` Alejandro Vallejo
  2025-04-28 10:41 ` Alejandro Vallejo
  2025-04-28 11:09 ` Andrew Cooper
  3 siblings, 1 reply; 10+ messages in thread
From: Roger Pau Monné @ 2025-04-28  9:41 UTC (permalink / raw)
  To: Ariadne Conill
  Cc: xen-devel, Paul Durrant, Jan Beulich, Andrew Cooper,
	Alejandro Vallejo, Alexander M . Merritt

On Fri, Apr 25, 2025 at 04:43:31PM -0700, 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.
> 
> Changes from v1:
> - Continue to use fixmap infrastructure
> - Use panic in Hyper-V setup() function instead of returning -ENOMEM
>   on hypercall page allocation failure
> 
> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
> Cc: Alejandro Vallejo <agarciav@amd.com>
> Cc: Alexander M. Merritt <alexander@edera.dev>
> Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
> ---
>  xen/arch/x86/guest/hyperv/hyperv.c      | 17 +++++++----------
>  xen/arch/x86/include/asm/guest/hyperv.h |  3 ---
>  2 files changed, 7 insertions(+), 13 deletions(-)
> 
> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
> index 6989af38f1..0305374a06 100644
> --- a/xen/arch/x86/guest/hyperv/hyperv.c
> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>      if ( !hypercall_msr.enable )
>      {
> -        mfn = HV_HCALL_MFN;
> +        void *hcall_page = alloc_xenheap_page();
> +        if ( !hcall_page )
> +            panic("Hyper-V: Failed to allocate hypercall trampoline page");
> +
> +        printk("Hyper-V: Allocated hypercall page @ %p.\n", hcall_page);

This likely wants to be a dprintk, and possibly also print the
physical address of the used page?  And no period at the end of the
sentence IMO.

I think Xen might have used the last page in the physical address
range to prevent HyperV from possibly shattering a superpage in the
second stage translation page-tables if normal RAM was used?

However I don't know whether HyperV will shatter super-pages if a
sub-page of it is used to contain the hypercall page (I don't think it
should?)

Thanks, Roger.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-25 23:43 [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls Ariadne Conill
  2025-04-28  7:00 ` Jan Beulich
  2025-04-28  9:41 ` Roger Pau Monné
@ 2025-04-28 10:41 ` Alejandro Vallejo
  2025-04-28 11:09 ` Andrew Cooper
  3 siblings, 0 replies; 10+ messages in thread
From: Alejandro Vallejo @ 2025-04-28 10:41 UTC (permalink / raw)
  To: Ariadne Conill, xen-devel
  Cc: Paul Durrant, Jan Beulich, Andrew Cooper, Roger Pau Monné,
	Alexander M . Merritt

On Sat Apr 26, 2025 at 12:43 AM BST, 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.

Thanks for sending this!

Just one more thing on top of what Jan mentioned.

>
> Changes from v1:
> - Continue to use fixmap infrastructure
> - Use panic in Hyper-V setup() function instead of returning -ENOMEM
>   on hypercall page allocation failure
>
> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
> Cc: Alejandro Vallejo <agarciav@amd.com>
> Cc: Alexander M. Merritt <alexander@edera.dev>
> Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
> ---
>  xen/arch/x86/guest/hyperv/hyperv.c      | 17 +++++++----------
>  xen/arch/x86/include/asm/guest/hyperv.h |  3 ---
>  2 files changed, 7 insertions(+), 13 deletions(-)
>
> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
> index 6989af38f1..0305374a06 100644
> --- a/xen/arch/x86/guest/hyperv/hyperv.c
> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>      if ( !hypercall_msr.enable )
>      {
> -        mfn = HV_HCALL_MFN;
> +        void *hcall_page = alloc_xenheap_page();
> +        if ( !hcall_page )
> +            panic("Hyper-V: Failed to allocate hypercall trampoline page");
> +
> +        printk("Hyper-V: Allocated hypercall page @ %p.\n", hcall_page);

We should be printing the mfn (or maddr) rather than the virtual address
out of the allocator, IMO. Especially since we need to remap it anyway.

With that:

  Reviewed-by: Alejandro Vallejo <agarciav@amd.com>

Cheers,
Alejandro


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-28  9:41 ` Roger Pau Monné
@ 2025-04-28 10:55   ` Alejandro Vallejo
  2025-04-28 11:07     ` Andrew Cooper
  0 siblings, 1 reply; 10+ messages in thread
From: Alejandro Vallejo @ 2025-04-28 10:55 UTC (permalink / raw)
  To: Roger Pau Monné, Ariadne Conill
  Cc: xen-devel, Paul Durrant, Jan Beulich, Andrew Cooper,
	Alexander M . Merritt

On Mon Apr 28, 2025 at 10:41 AM BST, Roger Pau Monné wrote:
> On Fri, Apr 25, 2025 at 04:43:31PM -0700, 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.
>> 
>> Changes from v1:
>> - Continue to use fixmap infrastructure
>> - Use panic in Hyper-V setup() function instead of returning -ENOMEM
>>   on hypercall page allocation failure
>> 
>> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
>> Cc: Alejandro Vallejo <agarciav@amd.com>
>> Cc: Alexander M. Merritt <alexander@edera.dev>
>> Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
>> ---
>>  xen/arch/x86/guest/hyperv/hyperv.c      | 17 +++++++----------
>>  xen/arch/x86/include/asm/guest/hyperv.h |  3 ---
>>  2 files changed, 7 insertions(+), 13 deletions(-)
>> 
>> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
>> index 6989af38f1..0305374a06 100644
>> --- a/xen/arch/x86/guest/hyperv/hyperv.c
>> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
>> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
>>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>>      if ( !hypercall_msr.enable )
>>      {
>> -        mfn = HV_HCALL_MFN;
>> +        void *hcall_page = alloc_xenheap_page();
>> +        if ( !hcall_page )
>> +            panic("Hyper-V: Failed to allocate hypercall trampoline page");
>> +
>> +        printk("Hyper-V: Allocated hypercall page @ %p.\n", hcall_page);
>
> This likely wants to be a dprintk, and possibly also print the
> physical address of the used page?  And no period at the end of the
> sentence IMO.
>
> I think Xen might have used the last page in the physical address
> range to prevent HyperV from possibly shattering a superpage in the
> second stage translation page-tables if normal RAM was used?
>
> However I don't know whether HyperV will shatter super-pages if a
> sub-page of it is used to contain the hypercall page (I don't think it
> should?)

I think it's quite unlikely. Seeing how Linux simply vmalloc()s and
Microsoft seems to genuinely care about Linux in this day and age. It
seems fair to assume Hyper-V might just copy the old memory out and
rewrite it with the trampoline contents when enabling the MSR, thereby
keeping superpages together in their p2m.

>
> Thanks, Roger.

Cheers,
Alejandro


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-28 10:55   ` Alejandro Vallejo
@ 2025-04-28 11:07     ` Andrew Cooper
  2025-04-28 11:50       ` Alejandro Vallejo
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Cooper @ 2025-04-28 11:07 UTC (permalink / raw)
  To: Alejandro Vallejo, Roger Pau Monné, Ariadne Conill, Wei Liu
  Cc: xen-devel, Paul Durrant, Jan Beulich, Alexander M . Merritt

On 28/04/2025 11:55 am, Alejandro Vallejo wrote:
> On Mon Apr 28, 2025 at 10:41 AM BST, Roger Pau Monné wrote:
>> On Fri, Apr 25, 2025 at 04:43:31PM -0700, 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.
>>>
>>> Changes from v1:
>>> - Continue to use fixmap infrastructure
>>> - Use panic in Hyper-V setup() function instead of returning -ENOMEM
>>>   on hypercall page allocation failure
>>>
>>> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
>>> Cc: Alejandro Vallejo <agarciav@amd.com>
>>> Cc: Alexander M. Merritt <alexander@edera.dev>
>>> Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
>>> ---
>>>  xen/arch/x86/guest/hyperv/hyperv.c      | 17 +++++++----------
>>>  xen/arch/x86/include/asm/guest/hyperv.h |  3 ---
>>>  2 files changed, 7 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
>>> index 6989af38f1..0305374a06 100644
>>> --- a/xen/arch/x86/guest/hyperv/hyperv.c
>>> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
>>> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
>>>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>>>      if ( !hypercall_msr.enable )
>>>      {
>>> -        mfn = HV_HCALL_MFN;
>>> +        void *hcall_page = alloc_xenheap_page();
>>> +        if ( !hcall_page )
>>> +            panic("Hyper-V: Failed to allocate hypercall trampoline page");
>>> +
>>> +        printk("Hyper-V: Allocated hypercall page @ %p.\n", hcall_page);
>> This likely wants to be a dprintk, and possibly also print the
>> physical address of the used page?  And no period at the end of the
>> sentence IMO.
>>
>> I think Xen might have used the last page in the physical address
>> range to prevent HyperV from possibly shattering a superpage in the
>> second stage translation page-tables if normal RAM was used?
>>
>> However I don't know whether HyperV will shatter super-pages if a
>> sub-page of it is used to contain the hypercall page (I don't think it
>> should?)
> I think it's quite unlikely.

It will shatter superpages.

The overlay is not part of guest memory, and will hide whatever is
behind it while it is mapped, which will force a 4k PTE in EPT/NPT.

Thinking about it, a better position would be adjacent to the APIC MMIO
window, so at 0xfee01000.  The APIC MMIO window is forced to be a 4k
mapping too, and the rest of the 2M window is normally empty.

~Andrew


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-25 23:43 [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls Ariadne Conill
                   ` (2 preceding siblings ...)
  2025-04-28 10:41 ` Alejandro Vallejo
@ 2025-04-28 11:09 ` Andrew Cooper
  3 siblings, 0 replies; 10+ messages in thread
From: Andrew Cooper @ 2025-04-28 11:09 UTC (permalink / raw)
  To: Ariadne Conill, xen-devel
  Cc: Paul Durrant, Jan Beulich, Roger Pau Monné,
	Alejandro Vallejo, Alexander M . Merritt

On 26/04/2025 12:43 am, Ariadne Conill wrote:
> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
> index 6989af38f1..0305374a06 100644
> --- a/xen/arch/x86/guest/hyperv/hyperv.c
> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>      if ( !hypercall_msr.enable )
>      {
> -        mfn = HV_HCALL_MFN;
> +        void *hcall_page = alloc_xenheap_page();
> +        if ( !hcall_page )
> +            panic("Hyper-V: Failed to allocate hypercall trampoline page");

\n

~Andrew


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-28 11:07     ` Andrew Cooper
@ 2025-04-28 11:50       ` Alejandro Vallejo
  2025-04-29  8:15         ` Roger Pau Monné
  0 siblings, 1 reply; 10+ messages in thread
From: Alejandro Vallejo @ 2025-04-28 11:50 UTC (permalink / raw)
  To: Andrew Cooper, Roger Pau Monné, Ariadne Conill, Wei Liu
  Cc: xen-devel, Paul Durrant, Jan Beulich, Alexander M . Merritt

On Mon Apr 28, 2025 at 12:07 PM BST, Andrew Cooper wrote:
> On 28/04/2025 11:55 am, Alejandro Vallejo wrote:
>> On Mon Apr 28, 2025 at 10:41 AM BST, Roger Pau Monné wrote:
>>> On Fri, Apr 25, 2025 at 04:43:31PM -0700, 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.
>>>>
>>>> Changes from v1:
>>>> - Continue to use fixmap infrastructure
>>>> - Use panic in Hyper-V setup() function instead of returning -ENOMEM
>>>>   on hypercall page allocation failure
>>>>
>>>> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
>>>> Cc: Alejandro Vallejo <agarciav@amd.com>
>>>> Cc: Alexander M. Merritt <alexander@edera.dev>
>>>> Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
>>>> ---
>>>>  xen/arch/x86/guest/hyperv/hyperv.c      | 17 +++++++----------
>>>>  xen/arch/x86/include/asm/guest/hyperv.h |  3 ---
>>>>  2 files changed, 7 insertions(+), 13 deletions(-)
>>>>
>>>> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
>>>> index 6989af38f1..0305374a06 100644
>>>> --- a/xen/arch/x86/guest/hyperv/hyperv.c
>>>> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
>>>> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
>>>>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>>>>      if ( !hypercall_msr.enable )
>>>>      {
>>>> -        mfn = HV_HCALL_MFN;
>>>> +        void *hcall_page = alloc_xenheap_page();
>>>> +        if ( !hcall_page )
>>>> +            panic("Hyper-V: Failed to allocate hypercall trampoline page");
>>>> +
>>>> +        printk("Hyper-V: Allocated hypercall page @ %p.\n", hcall_page);
>>> This likely wants to be a dprintk, and possibly also print the
>>> physical address of the used page?  And no period at the end of the
>>> sentence IMO.
>>>
>>> I think Xen might have used the last page in the physical address
>>> range to prevent HyperV from possibly shattering a superpage in the
>>> second stage translation page-tables if normal RAM was used?
>>>
>>> However I don't know whether HyperV will shatter super-pages if a
>>> sub-page of it is used to contain the hypercall page (I don't think it
>>> should?)
>> I think it's quite unlikely.
>
> It will shatter superpages.
>
> The overlay is not part of guest memory, and will hide whatever is
> behind it while it is mapped, which will force a 4k PTE in EPT/NPT.

That's an implementation detail. They can very well copy the trampoline
to guest memory when there is such (and save the previous contents
elsewhere) and restore them when disabling the trampoline. It's a
trivial optimisation that would prevent shattering while being fully
compliant with the TLFS.

The actual physical location of the trampoline is fully undefined. It
is defined to be an overlay; but that's a specification, not an
implementation.

>
> Thinking about it, a better position would be adjacent to the APIC MMIO
> window, so at 0xfee01000.  The APIC MMIO window is forced to be a 4k
> mapping too, and the rest of the 2M window is normally empty.
>

Sounds like an assumption waiting to be broken. Just like the last page
of guest-physical was.

Cheers,
Alejandro


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-28 11:50       ` Alejandro Vallejo
@ 2025-04-29  8:15         ` Roger Pau Monné
  2025-04-29 11:13           ` Alejandro Vallejo
  0 siblings, 1 reply; 10+ messages in thread
From: Roger Pau Monné @ 2025-04-29  8:15 UTC (permalink / raw)
  To: Alejandro Vallejo
  Cc: Andrew Cooper, Ariadne Conill, Wei Liu, xen-devel, Paul Durrant,
	Jan Beulich, Alexander M . Merritt

On Mon, Apr 28, 2025 at 12:50:55PM +0100, Alejandro Vallejo wrote:
> On Mon Apr 28, 2025 at 12:07 PM BST, Andrew Cooper wrote:
> > On 28/04/2025 11:55 am, Alejandro Vallejo wrote:
> >> On Mon Apr 28, 2025 at 10:41 AM BST, Roger Pau Monné wrote:
> >>> On Fri, Apr 25, 2025 at 04:43:31PM -0700, 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.
> >>>>
> >>>> Changes from v1:
> >>>> - Continue to use fixmap infrastructure
> >>>> - Use panic in Hyper-V setup() function instead of returning -ENOMEM
> >>>>   on hypercall page allocation failure
> >>>>
> >>>> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
> >>>> Cc: Alejandro Vallejo <agarciav@amd.com>
> >>>> Cc: Alexander M. Merritt <alexander@edera.dev>
> >>>> Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
> >>>> ---
> >>>>  xen/arch/x86/guest/hyperv/hyperv.c      | 17 +++++++----------
> >>>>  xen/arch/x86/include/asm/guest/hyperv.h |  3 ---
> >>>>  2 files changed, 7 insertions(+), 13 deletions(-)
> >>>>
> >>>> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
> >>>> index 6989af38f1..0305374a06 100644
> >>>> --- a/xen/arch/x86/guest/hyperv/hyperv.c
> >>>> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
> >>>> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
> >>>>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
> >>>>      if ( !hypercall_msr.enable )
> >>>>      {
> >>>> -        mfn = HV_HCALL_MFN;
> >>>> +        void *hcall_page = alloc_xenheap_page();
> >>>> +        if ( !hcall_page )
> >>>> +            panic("Hyper-V: Failed to allocate hypercall trampoline page");
> >>>> +
> >>>> +        printk("Hyper-V: Allocated hypercall page @ %p.\n", hcall_page);
> >>> This likely wants to be a dprintk, and possibly also print the
> >>> physical address of the used page?  And no period at the end of the
> >>> sentence IMO.
> >>>
> >>> I think Xen might have used the last page in the physical address
> >>> range to prevent HyperV from possibly shattering a superpage in the
> >>> second stage translation page-tables if normal RAM was used?
> >>>
> >>> However I don't know whether HyperV will shatter super-pages if a
> >>> sub-page of it is used to contain the hypercall page (I don't think it
> >>> should?)
> >> I think it's quite unlikely.
> >
> > It will shatter superpages.
> >
> > The overlay is not part of guest memory, and will hide whatever is
> > behind it while it is mapped, which will force a 4k PTE in EPT/NPT.
> 
> That's an implementation detail. They can very well copy the trampoline
> to guest memory when there is such (and save the previous contents
> elsewhere) and restore them when disabling the trampoline. It's a
> trivial optimisation that would prevent shattering while being fully
> compliant with the TLFS.

It's an implementation detail relevant from a guest perspective, as it
impacts guest performance.  IOW: we care about the specific (current)
implementation, as it's meaningful to how the guest-side should be
implemented.

> The actual physical location of the trampoline is fully undefined. It
> is defined to be an overlay; but that's a specification, not an
> implementation.
> 
> >
> > Thinking about it, a better position would be adjacent to the APIC MMIO
> > window, so at 0xfee01000.  The APIC MMIO window is forced to be a 4k
> > mapping too, and the rest of the 2M window is normally empty.
> >
> 
> Sounds like an assumption waiting to be broken. Just like the last page
> of guest-physical was.

As a compromise - could we try to allocate from < 4GB first, and
resort to high memory if that doesn't work?  That would at least limit
shattering (if done) to the low 4GB, which is quite likely fragmented
already:

hcall_page = alloc_xenheap_pages(0, MEMF_bits(32));
if ( !hcall_page )
    hcall_page = alloc_xenheap_page();
if ( !hcall_page )
    panic(...);

That will need a comment to describe what's going on.

Thanks, Roger.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls
  2025-04-29  8:15         ` Roger Pau Monné
@ 2025-04-29 11:13           ` Alejandro Vallejo
  0 siblings, 0 replies; 10+ messages in thread
From: Alejandro Vallejo @ 2025-04-29 11:13 UTC (permalink / raw)
  To: Roger Pau Monné
  Cc: Andrew Cooper, Ariadne Conill, Wei Liu, xen-devel, Paul Durrant,
	Jan Beulich, Alexander M . Merritt

On Tue Apr 29, 2025 at 9:15 AM BST, Roger Pau Monné wrote:
> On Mon, Apr 28, 2025 at 12:50:55PM +0100, Alejandro Vallejo wrote:
>> On Mon Apr 28, 2025 at 12:07 PM BST, Andrew Cooper wrote:
>> > On 28/04/2025 11:55 am, Alejandro Vallejo wrote:
>> >> On Mon Apr 28, 2025 at 10:41 AM BST, Roger Pau Monné wrote:
>> >>> On Fri, Apr 25, 2025 at 04:43:31PM -0700, 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.
>> >>>>
>> >>>> Changes from v1:
>> >>>> - Continue to use fixmap infrastructure
>> >>>> - Use panic in Hyper-V setup() function instead of returning -ENOMEM
>> >>>>   on hypercall page allocation failure
>> >>>>
>> >>>> Fixes: 620fc734f854 ("x86/hyperv: setup hypercall page")
>> >>>> Cc: Alejandro Vallejo <agarciav@amd.com>
>> >>>> Cc: Alexander M. Merritt <alexander@edera.dev>
>> >>>> Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
>> >>>> ---
>> >>>>  xen/arch/x86/guest/hyperv/hyperv.c      | 17 +++++++----------
>> >>>>  xen/arch/x86/include/asm/guest/hyperv.h |  3 ---
>> >>>>  2 files changed, 7 insertions(+), 13 deletions(-)
>> >>>>
>> >>>> diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
>> >>>> index 6989af38f1..0305374a06 100644
>> >>>> --- a/xen/arch/x86/guest/hyperv/hyperv.c
>> >>>> +++ b/xen/arch/x86/guest/hyperv/hyperv.c
>> >>>> @@ -98,7 +98,13 @@ static void __init setup_hypercall_page(void)
>> >>>>      rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>> >>>>      if ( !hypercall_msr.enable )
>> >>>>      {
>> >>>> -        mfn = HV_HCALL_MFN;
>> >>>> +        void *hcall_page = alloc_xenheap_page();
>> >>>> +        if ( !hcall_page )
>> >>>> +            panic("Hyper-V: Failed to allocate hypercall trampoline page");
>> >>>> +
>> >>>> +        printk("Hyper-V: Allocated hypercall page @ %p.\n", hcall_page);
>> >>> This likely wants to be a dprintk, and possibly also print the
>> >>> physical address of the used page?  And no period at the end of the
>> >>> sentence IMO.
>> >>>
>> >>> I think Xen might have used the last page in the physical address
>> >>> range to prevent HyperV from possibly shattering a superpage in the
>> >>> second stage translation page-tables if normal RAM was used?
>> >>>
>> >>> However I don't know whether HyperV will shatter super-pages if a
>> >>> sub-page of it is used to contain the hypercall page (I don't think it
>> >>> should?)
>> >> I think it's quite unlikely.
>> >
>> > It will shatter superpages.
>> >
>> > The overlay is not part of guest memory, and will hide whatever is
>> > behind it while it is mapped, which will force a 4k PTE in EPT/NPT.
>> 
>> That's an implementation detail. They can very well copy the trampoline
>> to guest memory when there is such (and save the previous contents
>> elsewhere) and restore them when disabling the trampoline. It's a
>> trivial optimisation that would prevent shattering while being fully
>> compliant with the TLFS.
>
> It's an implementation detail relevant from a guest perspective, as it
> impacts guest performance.  IOW: we care about the specific (current)
> implementation, as it's meaningful to how the guest-side should be
> implemented.

Indeed, I didn't mean otherwise.

My reply had more to do with the assertiveness of "it will shatter". The
reality is that we can't know, short of microbenching a read into the
trampoline after a TLB flush. And even then it may very well be
version-dependent (where old did, and newer doesn't, for instance).

>
>> The actual physical location of the trampoline is fully undefined. It
>> is defined to be an overlay; but that's a specification, not an
>> implementation.
>> 
>> >
>> > Thinking about it, a better position would be adjacent to the APIC MMIO
>> > window, so at 0xfee01000.  The APIC MMIO window is forced to be a 4k
>> > mapping too, and the rest of the 2M window is normally empty.
>> >
>> 
>> Sounds like an assumption waiting to be broken. Just like the last page
>> of guest-physical was.
>
> As a compromise - could we try to allocate from < 4GB first, and
> resort to high memory if that doesn't work?  That would at least limit
> shattering (if done) to the low 4GB, which is quite likely fragmented
> already:
>
> hcall_page = alloc_xenheap_pages(0, MEMF_bits(32));
> if ( !hcall_page )
>     hcall_page = alloc_xenheap_page();
> if ( !hcall_page )
>     panic(...);
>
> That will need a comment to describe what's going on.

Sounds far more resilient to me. I could get behind that, sure.

Ariadne, thoughts?

Cheers,
Alejandro


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-04-29 11:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-25 23:43 [PATCH v2] x86/hyperv: use dynamically allocated page for hypercalls Ariadne Conill
2025-04-28  7:00 ` Jan Beulich
2025-04-28  9:41 ` Roger Pau Monné
2025-04-28 10:55   ` Alejandro Vallejo
2025-04-28 11:07     ` Andrew Cooper
2025-04-28 11:50       ` Alejandro Vallejo
2025-04-29  8:15         ` Roger Pau Monné
2025-04-29 11:13           ` Alejandro Vallejo
2025-04-28 10:41 ` Alejandro Vallejo
2025-04-28 11:09 ` Andrew Cooper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.