[PATCH] x86/domain: adjust limitation on shared_info allocation below 4G

Roger Pau Monne posted 1 patch 3 days, 20 hours ago
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/20260203101017.56962-1-roger.pau@citrix.com
There is a newer version of this series
xen/arch/x86/domain.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
[PATCH] x86/domain: adjust limitation on shared_info allocation below 4G
Posted by Roger Pau Monne 3 days, 20 hours ago
The limitation of shared_info being allocated below 4G to fit in the
start_info field only applies to 32bit PV guests.  On 64bit PV guests the
start_info field is 64bits wide.  HVM guests don't use start_info at all.

Limit the allocation address restriction to 32bit PV guests only.

Fixes: 3cadc0469d5c ("x86_64: shared_info must be allocated below 4GB as it is advertised to 32-bit guests via a 32-bit machine address field in start_info.")
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
 xen/arch/x86/domain.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index edb76366b596..4163568043b1 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -882,10 +882,13 @@ int arch_domain_create(struct domain *d,
         goto fail;
 
     /*
-     * The shared_info machine address must fit in a 32-bit field within a
-     * 32-bit guest's start_info structure. Hence we specify MEMF_bits(32).
+     * For 32bit PV guests the shared_info machine address must fit in a 32-bit
+     * field within the guest's start_info structure. Hence we specify
+     * MEMF_bits(32).
      */
-    if ( (d->shared_info = alloc_xenheap_pages(0, MEMF_bits(32))) == NULL )
+    if ( (d->shared_info =
+          alloc_xenheap_pages(0, is_pv_32bit_domain(d) ? MEMF_bits(32)
+                                                       : 0)) == NULL )
         goto fail;
 
     clear_page(d->shared_info);
-- 
2.51.0


Re: [PATCH] x86/domain: adjust limitation on shared_info allocation below 4G
Posted by Roger Pau Monné 3 days, 20 hours ago
On Tue, Feb 03, 2026 at 11:10:17AM +0100, Roger Pau Monne wrote:
> The limitation of shared_info being allocated below 4G to fit in the
> start_info field only applies to 32bit PV guests.  On 64bit PV guests the
> start_info field is 64bits wide.  HVM guests don't use start_info at all.
> 
> Limit the allocation address restriction to 32bit PV guests only.
> 
> Fixes: 3cadc0469d5c ("x86_64: shared_info must be allocated below 4GB as it is advertised to 32-bit guests via a 32-bit machine address field in start_info.")
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> ---
>  xen/arch/x86/domain.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index edb76366b596..4163568043b1 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -882,10 +882,13 @@ int arch_domain_create(struct domain *d,
>          goto fail;
>  
>      /*
> -     * The shared_info machine address must fit in a 32-bit field within a
> -     * 32-bit guest's start_info structure. Hence we specify MEMF_bits(32).
> +     * For 32bit PV guests the shared_info machine address must fit in a 32-bit
> +     * field within the guest's start_info structure. Hence we specify
> +     * MEMF_bits(32).
>       */
> -    if ( (d->shared_info = alloc_xenheap_pages(0, MEMF_bits(32))) == NULL )
> +    if ( (d->shared_info =
> +          alloc_xenheap_pages(0, is_pv_32bit_domain(d) ? MEMF_bits(32)
> +                                                       : 0)) == NULL )

Sorry, this is wrong, it's too early to know whether the domain is 32
or 64bit.

Roger.

Re: [PATCH] x86/domain: adjust limitation on shared_info allocation below 4G
Posted by Andrew Cooper 2 days, 21 hours ago
On 03/02/2026 10:20 am, Roger Pau Monné wrote:
> On Tue, Feb 03, 2026 at 11:10:17AM +0100, Roger Pau Monne wrote:
>> The limitation of shared_info being allocated below 4G to fit in the
>> start_info field only applies to 32bit PV guests.  On 64bit PV guests the
>> start_info field is 64bits wide.  HVM guests don't use start_info at all.
>>
>> Limit the allocation address restriction to 32bit PV guests only.
>>
>> Fixes: 3cadc0469d5c ("x86_64: shared_info must be allocated below 4GB as it is advertised to 32-bit guests via a 32-bit machine address field in start_info.")
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> ---
>>  xen/arch/x86/domain.c | 9 ++++++---
>>  1 file changed, 6 insertions(+), 3 deletions(-)
>>
>> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
>> index edb76366b596..4163568043b1 100644
>> --- a/xen/arch/x86/domain.c
>> +++ b/xen/arch/x86/domain.c
>> @@ -882,10 +882,13 @@ int arch_domain_create(struct domain *d,
>>          goto fail;
>>  
>>      /*
>> -     * The shared_info machine address must fit in a 32-bit field within a
>> -     * 32-bit guest's start_info structure. Hence we specify MEMF_bits(32).
>> +     * For 32bit PV guests the shared_info machine address must fit in a 32-bit
>> +     * field within the guest's start_info structure. Hence we specify
>> +     * MEMF_bits(32).
>>       */
>> -    if ( (d->shared_info = alloc_xenheap_pages(0, MEMF_bits(32))) == NULL )
>> +    if ( (d->shared_info =
>> +          alloc_xenheap_pages(0, is_pv_32bit_domain(d) ? MEMF_bits(32)
>> +                                                       : 0)) == NULL )
> Sorry, this is wrong, it's too early to know whether the domain is 32
> or 64bit.

It's probably fine to have this become an unrestricted xenhelp
allocation, and for switch_compat() to make a restricted allocation and
copy.

When constructing a PV32 guest in practice, the set_compat hypercall is
only moments after from the domain create, and it doesn't matter if we
discover lowmem exhaustion marginally later

That way we don't have a PV32-ism continuing to impact the all VMs.

~Andrew

Re: [PATCH] x86/domain: adjust limitation on shared_info allocation below 4G
Posted by Roger Pau Monné 2 days, 21 hours ago
On Wed, Feb 04, 2026 at 09:41:21AM +0100, Andrew Cooper wrote:
> On 03/02/2026 10:20 am, Roger Pau Monné wrote:
> > On Tue, Feb 03, 2026 at 11:10:17AM +0100, Roger Pau Monne wrote:
> >> The limitation of shared_info being allocated below 4G to fit in the
> >> start_info field only applies to 32bit PV guests.  On 64bit PV guests the
> >> start_info field is 64bits wide.  HVM guests don't use start_info at all.
> >>
> >> Limit the allocation address restriction to 32bit PV guests only.
> >>
> >> Fixes: 3cadc0469d5c ("x86_64: shared_info must be allocated below 4GB as it is advertised to 32-bit guests via a 32-bit machine address field in start_info.")
> >> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> >> ---
> >>  xen/arch/x86/domain.c | 9 ++++++---
> >>  1 file changed, 6 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> >> index edb76366b596..4163568043b1 100644
> >> --- a/xen/arch/x86/domain.c
> >> +++ b/xen/arch/x86/domain.c
> >> @@ -882,10 +882,13 @@ int arch_domain_create(struct domain *d,
> >>          goto fail;
> >>  
> >>      /*
> >> -     * The shared_info machine address must fit in a 32-bit field within a
> >> -     * 32-bit guest's start_info structure. Hence we specify MEMF_bits(32).
> >> +     * For 32bit PV guests the shared_info machine address must fit in a 32-bit
> >> +     * field within the guest's start_info structure. Hence we specify
> >> +     * MEMF_bits(32).
> >>       */
> >> -    if ( (d->shared_info = alloc_xenheap_pages(0, MEMF_bits(32))) == NULL )
> >> +    if ( (d->shared_info =
> >> +          alloc_xenheap_pages(0, is_pv_32bit_domain(d) ? MEMF_bits(32)
> >> +                                                       : 0)) == NULL )
> > Sorry, this is wrong, it's too early to know whether the domain is 32
> > or 64bit.
> 
> It's probably fine to have this become an unrestricted xenhelp
> allocation, and for switch_compat() to make a restricted allocation and
> copy.

Yeah, that's what I'm doing.  It turns out to be a bit more
complicated that I originally anticipated, because you also need to
reset the v->vcpu_info_area.map filed to point to the new page.

> When constructing a PV32 guest in practice, the set_compat hypercall is
> only moments after from the domain create, and it doesn't matter if we
> discover lowmem exhaustion marginally later
> 
> That way we don't have a PV32-ism continuing to impact the all VMs.

Indeed, that's my approach, just took me a bit more than expected
because of the already taken references to the shared_info page by the
time switch_compat() is executed.

Regards, Roger.