new file mode 100644
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef X86_CPU_USER_REGS_H
+#define X86_CPU_USER_REGS_H
+
+#define DECL_REG_LOHI(which) union { \
+ uint64_t r ## which ## x; \
+ uint32_t e ## which ## x; \
+ uint16_t which ## x; \
+ struct { \
+ uint8_t which ## l; \
+ uint8_t which ## h; \
+ }; \
+}
+#define DECL_REG_LO8(name) union { \
+ uint64_t r ## name; \
+ uint32_t e ## name; \
+ uint16_t name; \
+ uint8_t name ## l; \
+}
+#define DECL_REG_LO16(name) union { \
+ uint64_t r ## name; \
+ uint32_t e ## name; \
+ uint16_t name; \
+}
+#define DECL_REG_HI(num) union { \
+ uint64_t r ## num; \
+ uint32_t r ## num ## d; \
+ uint16_t r ## num ## w; \
+ uint8_t r ## num ## b; \
+}
+
+struct cpu_user_regs
+{
+ DECL_REG_HI(15);
+ DECL_REG_HI(14);
+ DECL_REG_HI(13);
+ DECL_REG_HI(12);
+ DECL_REG_LO8(bp);
+ DECL_REG_LOHI(b);
+ DECL_REG_HI(11);
+ DECL_REG_HI(10);
+ DECL_REG_HI(9);
+ DECL_REG_HI(8);
+ DECL_REG_LOHI(a);
+ DECL_REG_LOHI(c);
+ DECL_REG_LOHI(d);
+ DECL_REG_LO8(si);
+ DECL_REG_LO8(di);
+ uint32_t error_code;
+ uint32_t entry_vector;
+ DECL_REG_LO16(ip);
+ uint16_t cs, _pad0[1];
+ uint8_t saved_upcall_mask;
+ uint8_t _pad1[3];
+ DECL_REG_LO16(flags); /* rflags.IF == !saved_upcall_mask */
+ DECL_REG_LO8(sp);
+ uint16_t ss, _pad2[3];
+ uint16_t es, _pad3[3];
+ uint16_t ds, _pad4[3];
+ uint16_t fs, _pad5[3];
+ uint16_t gs, _pad6[3];
+};
+
+#undef DECL_REG_HI
+#undef DECL_REG_LO16
+#undef DECL_REG_LO8
+#undef DECL_REG_LOHI
+
+#endif /* X86_CPU_USER_REGS_H */
@@ -9,7 +9,8 @@
#include <xen/percpu.h>
#include <xen/page-size.h>
-#include <public/xen.h>
+
+#include <asm/cpu-user-regs.h>
/*
* Xen's cpu stacks are 8 pages (8-page aligned), arranged as:
@@ -10,6 +10,8 @@
# include <xen/bug.h>
# include <xen/kernel.h>
+
+# include <asm/cpu-user-regs.h>
# include <asm/endbr.h>
# include <asm/msr-index.h>
# include <asm/x86-vendors.h>
@@ -114,6 +114,10 @@
#define __DECL_REG_LO16(name) uint32_t e ## name
#endif
+#ifdef __XEN__
+#define cpu_user_regs guest_user_regs
+#endif
+
struct cpu_user_regs {
__DECL_REG_LO8(b);
__DECL_REG_LO8(c);
@@ -139,6 +143,10 @@ struct cpu_user_regs {
typedef struct cpu_user_regs cpu_user_regs_t;
DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
+#ifdef __XEN__
+#undef cpu_user_regs
+#endif
+
#undef __DECL_REG_LO8
#undef __DECL_REG_LO16
@@ -159,6 +159,10 @@ struct iret_context {
#define __DECL_REG_HI(num) uint64_t r ## num
#endif
+#ifdef __XEN__
+#define cpu_user_regs guest_user_regs
+#endif
+
struct cpu_user_regs {
__DECL_REG_HI(15);
__DECL_REG_HI(14);
@@ -192,6 +196,10 @@ struct cpu_user_regs {
typedef struct cpu_user_regs cpu_user_regs_t;
DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
+#ifdef __XEN__
+#undef cpu_user_regs
+#endif
+
#undef __DECL_REG
#undef __DECL_REG_LOHI
#undef __DECL_REG_LO8
@@ -173,7 +173,13 @@ struct vcpu_guest_context {
#define _VGCF_online 5
#define VGCF_online (1<<_VGCF_online)
unsigned long flags; /* VGCF_* flags */
+
+#ifdef __XEN__
+ struct guest_user_regs user_regs; /* User-level CPU registers */
+#else
struct cpu_user_regs user_regs; /* User-level CPU registers */
+#endif
+
struct trap_info trap_ctxt[256]; /* Virtual IDT */
unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */
unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
In order to support FRED, we're going to have to remove the {ds..gs} fields from struct cpu_user_regs, meaning that it is going to have to become a different type to the structure embedded in vcpu_guest_context_u. struct cpu_user_regs is a name used in common Xen code (i.e. needs to stay using this name), so renaming the public struct to be guest_user_regs in Xen's view only. Introduce a brand hew cpu-user-regs.h, currently containing a duplicate structure. This removes the need for current.h to include public/xen.h, and highlights a case where the emulator was picking up cpu_user_regs transitively. No functional change. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> --- CC: Jan Beulich <JBeulich@suse.com> CC: Roger Pau Monné <roger.pau@citrix.com> Jan: Is this what you intended? cpu_user_regs_t and the guest handle don't seem to be used anywhere. I'm tempted to exclude them from Xen builds. --- xen/arch/x86/include/asm/cpu-user-regs.h | 69 ++++++++++++++++++++++++ xen/arch/x86/include/asm/current.h | 3 +- xen/arch/x86/x86_emulate/private.h | 2 + xen/include/public/arch-x86/xen-x86_32.h | 8 +++ xen/include/public/arch-x86/xen-x86_64.h | 8 +++ xen/include/public/arch-x86/xen.h | 6 +++ 6 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 xen/arch/x86/include/asm/cpu-user-regs.h