[PATCH] x86/domctl: Reorder user_regs accesses for efficiency

Andrew Cooper posted 1 patch 3 days, 11 hours ago
Failed in applying to current master (apply log)
xen/arch/x86/domain.c |  6 +++---
xen/arch/x86/domctl.c | 10 +++++-----
2 files changed, 8 insertions(+), 8 deletions(-)
[PATCH] x86/domctl: Reorder user_regs accesses for efficiency
Posted by Andrew Cooper 3 days, 11 hours ago
The current order is derived from expanding XLAT_cpu_user_regs() which uses
the x86_32 cpu_user_regs order.  This is correct for one the blocks, but not
the others.

In order to work with the prefetcher, rather than against it, loads want to be
in field order.  Make this so for the three paths reading an x86_64
cpu_user_regs.

No functional change.

Reported-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <jbeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Teddy Astie <teddy.astie@vates.tech>
CC: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
 xen/arch/x86/domain.c |  6 +++---
 xen/arch/x86/domctl.c | 10 +++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 53a86ba373a4..996b50af7a17 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1259,17 +1259,17 @@ int arch_set_info_guest(
         v->arch.user_regs.r14               = c.nat->user_regs.r14;
         v->arch.user_regs.r13               = c.nat->user_regs.r13;
         v->arch.user_regs.r12               = c.nat->user_regs.r12;
+        v->arch.user_regs.rbp               = c.nat->user_regs.rbp;
+        v->arch.user_regs.rbx               = c.nat->user_regs.rbx;
         v->arch.user_regs.r11               = c.nat->user_regs.r11;
         v->arch.user_regs.r10               = c.nat->user_regs.r10;
         v->arch.user_regs.r9                = c.nat->user_regs.r9;
         v->arch.user_regs.r8                = c.nat->user_regs.r8;
-        v->arch.user_regs.rbx               = c.nat->user_regs.rbx;
+        v->arch.user_regs.rax               = c.nat->user_regs.rax;
         v->arch.user_regs.rcx               = c.nat->user_regs.rcx;
         v->arch.user_regs.rdx               = c.nat->user_regs.rdx;
         v->arch.user_regs.rsi               = c.nat->user_regs.rsi;
         v->arch.user_regs.rdi               = c.nat->user_regs.rdi;
-        v->arch.user_regs.rbp               = c.nat->user_regs.rbp;
-        v->arch.user_regs.rax               = c.nat->user_regs.rax;
         v->arch.user_regs.rip               = c.nat->user_regs.rip;
         v->arch.user_regs.cs                = c.nat->user_regs.cs;
         v->arch.user_regs.rflags            = (c.nat->user_regs.rflags & X86_EFLAGS_ALL) | X86_EFLAGS_MBS;
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 3ea4c650eee0..2ecd81d89b09 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1485,17 +1485,17 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
         c.nat->user_regs.r14               = v->arch.user_regs.r14;
         c.nat->user_regs.r13               = v->arch.user_regs.r13;
         c.nat->user_regs.r12               = v->arch.user_regs.r12;
+        c.nat->user_regs.rbp               = v->arch.user_regs.rbp;
+        c.nat->user_regs.rbx               = v->arch.user_regs.rbx;
         c.nat->user_regs.r11               = v->arch.user_regs.r11;
         c.nat->user_regs.r10               = v->arch.user_regs.r10;
         c.nat->user_regs.r9                = v->arch.user_regs.r9;
         c.nat->user_regs.r8                = v->arch.user_regs.r8;
-        c.nat->user_regs.rbx               = v->arch.user_regs.rbx;
+        c.nat->user_regs.rax               = v->arch.user_regs.rax;
         c.nat->user_regs.rcx               = v->arch.user_regs.rcx;
         c.nat->user_regs.rdx               = v->arch.user_regs.rdx;
         c.nat->user_regs.rsi               = v->arch.user_regs.rsi;
         c.nat->user_regs.rdi               = v->arch.user_regs.rdi;
-        c.nat->user_regs.rbp               = v->arch.user_regs.rbp;
-        c.nat->user_regs.rax               = v->arch.user_regs.rax;
         c.nat->user_regs.rip               = v->arch.user_regs.rip;
         c.nat->user_regs.cs                = v->arch.user_regs.cs;
         c.nat->user_regs.rflags            = v->arch.user_regs.rflags;
@@ -1514,13 +1514,13 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
     else
     {
         /* Backing memory is pre-zeroed. */
+        c.cmp->user_regs.ebp               = v->arch.user_regs.ebp;
         c.cmp->user_regs.ebx               = v->arch.user_regs.ebx;
+        c.cmp->user_regs.eax               = v->arch.user_regs.eax;
         c.cmp->user_regs.ecx               = v->arch.user_regs.ecx;
         c.cmp->user_regs.edx               = v->arch.user_regs.edx;
         c.cmp->user_regs.esi               = v->arch.user_regs.esi;
         c.cmp->user_regs.edi               = v->arch.user_regs.edi;
-        c.cmp->user_regs.ebp               = v->arch.user_regs.ebp;
-        c.cmp->user_regs.eax               = v->arch.user_regs.eax;
         c.cmp->user_regs.eip               = v->arch.user_regs.eip;
         c.cmp->user_regs.cs                = v->arch.user_regs.cs;
         c.cmp->user_regs.eflags            = v->arch.user_regs.eflags;
-- 
2.39.5


Re: [PATCH] x86/domctl: Reorder user_regs accesses for efficiency
Posted by Teddy Astie 3 days, 10 hours ago
Le 20/07/2026 à 11:22, Andrew Cooper a écrit :
> The current order is derived from expanding XLAT_cpu_user_regs() which uses
> the x86_32 cpu_user_regs order.  This is correct for one the blocks, but not
> the others.
> 
> In order to work with the prefetcher, rather than against it, loads want to be
> in field order.  Make this so for the three paths reading an x86_64
> cpu_user_regs.
> 
> No functional change.
> 
> Reported-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
Re: [PATCH] x86/domctl: Reorder user_regs accesses for efficiency
Posted by Frediano Ziglio 3 days, 10 hours ago
On Mon, 20 Jul 2026 at 10:38, Andrew Cooper <andrew.cooper3@citrix.com> wrote:
>
> The current order is derived from expanding XLAT_cpu_user_regs() which uses
> the x86_32 cpu_user_regs order.  This is correct for one the blocks, but not
> the others.
>
> In order to work with the prefetcher, rather than against it, loads want to be
> in field order.  Make this so for the three paths reading an x86_64
> cpu_user_regs.
>
> No functional change.
>
> Reported-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <jbeulich@suse.com>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> CC: Teddy Astie <teddy.astie@vates.tech>
> CC: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
> ---
>  xen/arch/x86/domain.c |  6 +++---
>  xen/arch/x86/domctl.c | 10 +++++-----
>  2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index 53a86ba373a4..996b50af7a17 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -1259,17 +1259,17 @@ int arch_set_info_guest(
>          v->arch.user_regs.r14               = c.nat->user_regs.r14;
>          v->arch.user_regs.r13               = c.nat->user_regs.r13;
>          v->arch.user_regs.r12               = c.nat->user_regs.r12;
> +        v->arch.user_regs.rbp               = c.nat->user_regs.rbp;
> +        v->arch.user_regs.rbx               = c.nat->user_regs.rbx;
>          v->arch.user_regs.r11               = c.nat->user_regs.r11;
>          v->arch.user_regs.r10               = c.nat->user_regs.r10;
>          v->arch.user_regs.r9                = c.nat->user_regs.r9;
>          v->arch.user_regs.r8                = c.nat->user_regs.r8;
> -        v->arch.user_regs.rbx               = c.nat->user_regs.rbx;
> +        v->arch.user_regs.rax               = c.nat->user_regs.rax;
>          v->arch.user_regs.rcx               = c.nat->user_regs.rcx;
>          v->arch.user_regs.rdx               = c.nat->user_regs.rdx;
>          v->arch.user_regs.rsi               = c.nat->user_regs.rsi;
>          v->arch.user_regs.rdi               = c.nat->user_regs.rdi;
> -        v->arch.user_regs.rbp               = c.nat->user_regs.rbp;
> -        v->arch.user_regs.rax               = c.nat->user_regs.rax;
>          v->arch.user_regs.rip               = c.nat->user_regs.rip;
>          v->arch.user_regs.cs                = c.nat->user_regs.cs;
>          v->arch.user_regs.rflags            = (c.nat->user_regs.rflags & X86_EFLAGS_ALL) | X86_EFLAGS_MBS;
> diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
> index 3ea4c650eee0..2ecd81d89b09 100644
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -1485,17 +1485,17 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
>          c.nat->user_regs.r14               = v->arch.user_regs.r14;
>          c.nat->user_regs.r13               = v->arch.user_regs.r13;
>          c.nat->user_regs.r12               = v->arch.user_regs.r12;
> +        c.nat->user_regs.rbp               = v->arch.user_regs.rbp;
> +        c.nat->user_regs.rbx               = v->arch.user_regs.rbx;
>          c.nat->user_regs.r11               = v->arch.user_regs.r11;
>          c.nat->user_regs.r10               = v->arch.user_regs.r10;
>          c.nat->user_regs.r9                = v->arch.user_regs.r9;
>          c.nat->user_regs.r8                = v->arch.user_regs.r8;
> -        c.nat->user_regs.rbx               = v->arch.user_regs.rbx;
> +        c.nat->user_regs.rax               = v->arch.user_regs.rax;
>          c.nat->user_regs.rcx               = v->arch.user_regs.rcx;
>          c.nat->user_regs.rdx               = v->arch.user_regs.rdx;
>          c.nat->user_regs.rsi               = v->arch.user_regs.rsi;
>          c.nat->user_regs.rdi               = v->arch.user_regs.rdi;
> -        c.nat->user_regs.rbp               = v->arch.user_regs.rbp;
> -        c.nat->user_regs.rax               = v->arch.user_regs.rax;
>          c.nat->user_regs.rip               = v->arch.user_regs.rip;
>          c.nat->user_regs.cs                = v->arch.user_regs.cs;
>          c.nat->user_regs.rflags            = v->arch.user_regs.rflags;
> @@ -1514,13 +1514,13 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
>      else
>      {
>          /* Backing memory is pre-zeroed. */
> +        c.cmp->user_regs.ebp               = v->arch.user_regs.ebp;
>          c.cmp->user_regs.ebx               = v->arch.user_regs.ebx;
> +        c.cmp->user_regs.eax               = v->arch.user_regs.eax;
>          c.cmp->user_regs.ecx               = v->arch.user_regs.ecx;
>          c.cmp->user_regs.edx               = v->arch.user_regs.edx;
>          c.cmp->user_regs.esi               = v->arch.user_regs.esi;
>          c.cmp->user_regs.edi               = v->arch.user_regs.edi;
> -        c.cmp->user_regs.ebp               = v->arch.user_regs.ebp;
> -        c.cmp->user_regs.eax               = v->arch.user_regs.eax;
>          c.cmp->user_regs.eip               = v->arch.user_regs.eip;
>          c.cmp->user_regs.cs                = v->arch.user_regs.cs;
>          c.cmp->user_regs.eflags            = v->arch.user_regs.eflags;

Reviewed-by: Frediano Ziglio <frediano.ziglio@citrix.com>

Frediano
Re: [PATCH] x86/domctl: Reorder user_regs accesses for efficiency
Posted by Jan Beulich 3 days, 11 hours ago
On 20.07.2026 11:22, Andrew Cooper wrote:
> The current order is derived from expanding XLAT_cpu_user_regs() which uses
> the x86_32 cpu_user_regs order.  This is correct for one the blocks, but not
> the others.
> 
> In order to work with the prefetcher, rather than against it, loads want to be
> in field order.  Make this so for the three paths reading an x86_64
> cpu_user_regs.
> 
> No functional change.
> 
> Reported-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>