[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH RFC] x86/PV: avoid HVM-copying alternatives in PV-only code


  • To: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Tue, 21 Jul 2026 09:17:58 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=google header.d=suse.com header.i="@suse.com" header.h="Content-Transfer-Encoding:Content-Type:In-Reply-To:Autocrypt:From:Content-Language:References:Cc:To:Subject:User-Agent:MIME-Version:Date:Message-ID"
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: Roger Pau Monné <roger.pau@xxxxxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Tue, 21 Jul 2026 07:18:09 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 20.07.2026 22:07, Andrew Cooper wrote:
> On 30/06/2026 2:38 pm, Jan Beulich wrote:
>> --- a/xen/arch/x86/include/asm/guest_access.h
>> +++ b/xen/arch/x86/include/asm/guest_access.h
>> @@ -14,11 +14,15 @@
>>  
>>  /* Raw access functions: no type checking. */
>>  #define raw_copy_to_guest(dst, src, len)        \
>> -    (is_hvm_vcpu(current) ?                     \
>> +    ((IS_ENABLED(HVM_ONLY_SOURCE) ||            \
>> +      (!IS_ENABLED(PV_ONLY_SOURCE) &&           \
>> +       is_hvm_vcpu(current))) ?                 \
>>       copy_to_user_hvm((dst), (src), (len)) :    \
>>       copy_to_guest_pv(dst, src, len))
>>  #define raw_copy_from_guest(dst, src, len)      \
>> -    (is_hvm_vcpu(current) ?                     \
>> +    ((IS_ENABLED(HVM_ONLY_SOURCE) ||            \
>> +      (!IS_ENABLED(PV_ONLY_SOURCE) &&           \
>> +       is_hvm_vcpu(current))) ?                 \
>>       copy_from_user_hvm((dst), (src), (len)) :  \
>>       copy_from_guest_pv(dst, src, len))
>>  #define raw_clear_guest(dst,  len)              \
>> @@ -26,11 +30,15 @@
>>       clear_user_hvm((dst), (len)) :             \
>>       clear_guest_pv(dst, len))
>>  #define __raw_copy_to_guest(dst, src, len)      \
>> -    (is_hvm_vcpu(current) ?                     \
>> +    ((IS_ENABLED(HVM_ONLY_SOURCE) ||            \
>> +      (!IS_ENABLED(PV_ONLY_SOURCE) &&           \
>> +       is_hvm_vcpu(current))) ?                 \
>>       copy_to_user_hvm((dst), (src), (len)) :    \
>>       __copy_to_guest_pv(dst, src, len))
>>  #define __raw_copy_from_guest(dst, src, len)    \
>> -    (is_hvm_vcpu(current) ?                     \
>> +    ((IS_ENABLED(HVM_ONLY_SOURCE) ||            \
>> +      (!IS_ENABLED(PV_ONLY_SOURCE) &&           \
>> +       is_hvm_vcpu(current))) ?                 \
>>       copy_from_user_hvm((dst), (src), (len)) :  \
>>       __copy_from_guest_pv(dst, src, len))
> 
> Looking back at my own attempt to do this, which was from August 2024, I
> started by cleaning up this code block as such:
> 
> --- a/xen/arch/x86/include/asm/guest_access.h
> +++ b/xen/arch/x86/include/asm/guest_access.h
> @@ -12,27 +12,33 @@
>  #include <asm/hvm/support.h>
>  #include <asm/hvm/guest_access.h>
>  
> +#define GUEST_ACCESS_HVM is_hvm_vcpu(current)
> +
>  /* Raw access functions: no type checking. */
>  #define raw_copy_to_guest(dst, src, len)        \
> -    (is_hvm_vcpu(current) ?                     \
> -     copy_to_user_hvm((dst), (src), (len)) :    \
> -     copy_to_guest_pv(dst, src, len))
> +    (GUEST_ACCESS_HVM                           \
> +     ? copy_to_user_hvm(dst, src, len)          \
> +     : copy_to_guest_pv(dst, src, len))
> +
>  #define raw_copy_from_guest(dst, src, len)      \
> -    (is_hvm_vcpu(current) ?                     \
> -     copy_from_user_hvm((dst), (src), (len)) :  \
> -     copy_from_guest_pv(dst, src, len))
> +    (GUEST_ACCESS_HVM                           \
> +     ? copy_from_user_hvm(dst, src, len)        \
> +     : copy_from_guest_pv(dst, src, len))
> +
>  #define raw_clear_guest(dst,  len)              \
> -    (is_hvm_vcpu(current) ?                     \
> -     clear_user_hvm((dst), (len)) :             \
> -     clear_guest_pv(dst, len))
> +    (GUEST_ACCESS_HVM                           \
> +     ? clear_user_hvm(dst, len)                 \
> +     : clear_guest_pv(dst, len))
> +
>  #define __raw_copy_to_guest(dst, src, len)      \
> -    (is_hvm_vcpu(current) ?                     \
> -     copy_to_user_hvm((dst), (src), (len)) :    \
> -     __copy_to_guest_pv(dst, src, len))
> +    (GUEST_ACCESS_HVM                           \
> +     ?   copy_to_user_hvm(dst, src, len)        \
> +     : __copy_to_guest_pv(dst, src, len))
> +
>  #define __raw_copy_from_guest(dst, src, len)    \
> -    (is_hvm_vcpu(current) ?                     \
> -     copy_from_user_hvm((dst), (src), (len)) :  \
> -     __copy_from_guest_pv(dst, src, len))
> +    (GUEST_ACCESS_HVM                           \
> +     ?   copy_from_user_hvm(dst, src, len)      \
> +     : __copy_from_guest_pv(dst, src, len))
>  
>  /*
>   * Pre-validate a guest handle.
> 
> 
> 
> so they're all consistent and legible,

Sure, why not. There's one Misra concern though: In my patch I'm
specifically avoiding (naming aside)

#define GUEST_ACCESS_HVM is_hvm_vcpu(current)

in the header, as that then requires #undef elsewhere to override. Misra
wants us to avoid #undef as much as possible. In x86/mm.c this then would
also require the original form to be re-instated. (Yes, I'm not getting
away without #undef either, but it's truly removal of the definition, not
removal to then re-instate the macro with a different expansion.)

Perhaps something like

#define IS_HVM_ACCESS                    \
    (IS_ENABLED(GUEST_ACCESS_HVM) ||     \
     (!IS_ENABLED(GUEST_ACCESS_PV) &&    \
      is_hvm_vcpu(current)))             \

to reduce redundancy in the macros while keeping the property of my patch?

> then extended GUEST_ACCESS_HVM to:
> 
> --- a/xen/arch/x86/include/asm/guest_access.h
> +++ b/xen/arch/x86/include/asm/guest_access.h
> @@ -12,7 +12,12 @@
>  #include <asm/hvm/support.h>
>  #include <asm/hvm/guest_access.h>
>  
> -#define GUEST_ACCESS_HVM is_hvm_vcpu(current)
> +#define GUEST_ACCESS_HVM                        \
> +    (IS_ENABLED(GA_ALWAYS_PV)                   \
> +     ? 0                                        \
> +     : (IS_ENABLED(GA_ALWAYS_HVM)               \
> +        ? 1                                     \
> +        : is_hvm_vcpu(current)))                \
>  
>  /* Raw access functions: no type checking. */
>  #define raw_copy_to_guest(dst, src, len)        \
> 
> 
> 
> to allow ways to force it one way or another.

Sure, perhaps simplified to

#define GUEST_ACCESS_HVM                        \
    (IS_ENABLED(GA_ALWAYS_PV)                   \
     ? false                                    \
     : (IS_ENABLED(GA_ALWAYS_HVM) ||            \
        is_hvm_vcpu(current)))                  \

or something yet closer to what I have in my patch. The conditional
operators aren't overly useful here.

Yet one of the RFC questions remains with this: Is there anywhere we'd
actually be able to use GA_ALWAYS_HVM?

> For forcing it one way or another, while ...
> 
>> --- a/xen/arch/x86/mm.c
>> +++ b/xen/arch/x86/mm.c
>> @@ -3407,6 +3407,9 @@ int new_guest_cr3(mfn_t mfn)
>>  #endif
>>  
>>  #ifdef CONFIG_PV
>> +
>> +#define PV_ONLY_SOURCE 1
>> +
> 
> ... mm.c is certainly complicated, others like ...
> 
>> --- a/xen/arch/x86/pv/callback.c
>> +++ b/xen/arch/x86/pv/callback.c
>> @@ -5,6 +5,8 @@
>>   * hypercall handles and helper functions for guest callback
>>   */
>>  
>> +#define PV_ONLY_SOURCE 1
>> +
>>  #include <xen/event.h>
>>  #include <xen/hypercall.h>
>>  #include <xen/guest_access.h>
>> --- a/xen/arch/x86/pv/descriptor-tables.c
>> +++ b/xen/arch/x86/pv/descriptor-tables.c
>> @@ -8,6 +8,8 @@
>>   * Copyright (c) 2004 Christian Limpach
>>   */
>>  
>> +#define PV_ONLY_SOURCE 1
>> +
>>  #include <xen/guest_access.h>
>>  #include <xen/hypercall.h>
>>  
>> --- a/xen/arch/x86/pv/shim.c
>> +++ b/xen/arch/x86/pv/shim.c
>> @@ -6,6 +6,9 @@
>>   *
>>   * Copyright (c) 2017 Citrix Systems Ltd.
>>   */
>> +
>> +#define PV_ONLY_SOURCE 1
>> +
>>  #include <xen/event.h>
>>  #include <xen/guest_access.h>
>>  #include <xen/hypercall.h>
> 
> all of these could have a general CFLAGS += in arch/x86/pv/Makefile
> rather than having to state it in every file.

A general CFLAGS += is (at least latently / conceptually) wrong in pv/,
as code there may come into play when a PVH Dom0 controls a PV DomU. Much
like a fair bit of care is needed in x86/mm.c (where we may want to try
to move some more code to x86/pv/mm.c).

I did consider this on a per-object basis and meant to put in a remark to
this effect, but then forgot. The issue I see with using this approach is
the disconnect between setting of the control (Makefile) and it being
correct to use for the particular source file (in particular when making
changes down the road). Having the #define near the top of the files has
(imo) at least slightly better chances of being noticed when opening the
file for editing.

> Naming wise, while PV_ONLY_SOURCE works in pv/, it's more dubious in
> arch/x86/mm.c.  GUEST_ACCESS_* at least identifies the property that's
> being decided upon.

I'm happy to see your naming used; I wasn't overly happy with my naming
choice anyway.

Jan



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.