]> xenbits.xensource.com Git - people/andrewcoop/xen.git/commitdiff
x86: Drop the vm86 segments selectors from struct cpu_user_regs
authorAndrew Cooper <andrew.cooper3@citrix.com>
Sun, 29 Dec 2024 14:46:34 +0000 (14:46 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 11 Mar 2025 20:11:08 +0000 (20:11 +0000)
The data segment registers are part of the on-stack IRET frame when
interrupting Virtual 8086 mode, but this ceased being relevant for Xen in
commit 5d1181a5ea5e ("xen: Remove x86_32 build target.") in 2012.

With all other cleanup in place, delete the fields so we can introduce FRED
support which uses this space for different data.

Everywhere which used the es field as an offset in cpu_user_regs needs
adjusting.  However, they'll change again for FRED, so no cleanup is performed
at this juncture.

This also undoes the OoB Read workaround in show_registers(), which can now
switch back to being simple structure copy.

No functional change, but a lot of rearranging of stack and struct layout
under the hood.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
xen/arch/x86/cpu/common.c
xen/arch/x86/include/asm/cpu-user-regs.h
xen/arch/x86/include/asm/current.h
xen/arch/x86/include/asm/hvm/hvm.h
xen/arch/x86/include/asm/regs.h
xen/arch/x86/traps.c
xen/arch/x86/x86_64/asm-offsets.c
xen/arch/x86/x86_64/traps.c

index b934ce7ca487a6d5a3a4ea8e2c1416a5bfe7caeb..654f847e1f8ca3227a0531f8a46a944c9edf7816 100644 (file)
@@ -917,7 +917,7 @@ void load_system_tables(void)
         * Defer checks until exception support is sufficiently set up.
         */
        BUILD_BUG_ON((sizeof(struct cpu_info) -
-                     offsetof(struct cpu_info, guest_cpu_user_regs.es)) & 0xf);
+                     sizeof(struct cpu_user_regs)) & 0xf);
        BUG_ON(system_state != SYS_STATE_early_boot && (stack_bottom & 0xf));
 }
 
index 845b41a22ef2fe81522f6c4a2b04c1735406d28b..c4cc8640c23f6d5559f1f062ee34c0c74cecd523 100644 (file)
@@ -55,10 +55,6 @@ struct cpu_user_regs
     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
index 243d17ef79fd23c022b3078acc908f2cb96a71d6..a7c9473428b2c7214082a02bd84f47811bbf2961 100644 (file)
@@ -106,12 +106,12 @@ static inline struct cpu_info *get_cpu_info(void)
 #define get_per_cpu_offset()  (get_cpu_info()->per_cpu_offset)
 
 /*
- * Get the bottom-of-stack, as stored in the per-CPU TSS. This actually points
- * into the middle of cpu_info.guest_cpu_user_regs, at the section that
- * precisely corresponds to a CPU trap frame.
+ * Get the bottom-of-stack, as stored in the per-CPU TSS. This points at the
+ * end of cpu_info.guest_cpu_user_regs, at the section that precisely
+ * corresponds to a CPU trap frame.
  */
 #define get_stack_bottom()                      \
-    ((unsigned long)&get_cpu_info()->guest_cpu_user_regs.es)
+    ((unsigned long)(&get_cpu_info()->guest_cpu_user_regs + 1))
 
 /*
  * Get the reasonable stack bounds for stack traces and stack dumps.  Stack
index 963e8201130a9c822299d1762916e4b7d414d6b4..cde6efd7adc09d06e14fbfe2543cff03fdf59655 100644 (file)
@@ -624,10 +624,6 @@ static inline void hvm_sanitize_regs_fields(struct cpu_user_regs *regs,
     regs->saved_upcall_mask = 0xbf;
     regs->cs = 0xbeef;
     regs->ss = 0xbeef;
-    regs->ds = 0xbeef;
-    regs->es = 0xbeef;
-    regs->fs = 0xbeef;
-    regs->gs = 0xbeef;
 #endif
 }
 
index c05b9207c281503bdba552adf7963cb34abd1f35..dcc45ac5af7f245a6d3e7fe7d0a99ae38ef886a0 100644 (file)
@@ -20,8 +20,7 @@
     (!is_pv_32bit_vcpu(v) ? ((tb)->eip == 0) : (((tb)->cs & ~3) == 0))
 
 /* Number of bytes of on-stack execution state to be context-switched. */
-/* NB. Segment registers and bases are not saved/restored on x86/64 stack. */
-#define CTXT_SWITCH_STACK_BYTES (offsetof(struct cpu_user_regs, es))
+#define CTXT_SWITCH_STACK_BYTES sizeof(struct cpu_user_regs)
 
 #define guest_mode(r)                                                         \
 ({                                                                            \
index 5addb1f903d3adc5a1b53204a43f8b267f41432e..27e68285e50493d763f7fb1a3d91faf56e9b5c13 100644 (file)
@@ -416,7 +416,7 @@ unsigned long get_stack_trace_bottom(unsigned long sp)
     {
     case 1 ... 4:
         return ROUNDUP(sp, PAGE_SIZE) -
-            offsetof(struct cpu_user_regs, es) - sizeof(unsigned long);
+            sizeof(struct cpu_user_regs) - sizeof(unsigned long);
 
     case 6 ... 7:
         return ROUNDUP(sp, STACK_SIZE) -
index 630bdc39451d96c15eb0f298b984789f06d76593..2258b4ce1b957453c64d42926df9b854c024038e 100644 (file)
@@ -52,7 +52,7 @@ void __dummy__(void)
     OFFSET(UREGS_eflags, struct cpu_user_regs, rflags);
     OFFSET(UREGS_rsp, struct cpu_user_regs, rsp);
     OFFSET(UREGS_ss, struct cpu_user_regs, ss);
-    OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, es);
+    DEFINE(UREGS_kernel_sizeof, sizeof(struct cpu_user_regs));
     BLANK();
 
     /*
index cb06f99021d1e1c018f2beabc524408368d84a03..78c5b7a1e300ebfff3eb17d9a9a4f34e18057874 100644 (file)
@@ -134,17 +134,11 @@ static void _show_registers(
 
 void show_registers(const struct cpu_user_regs *regs)
 {
-    struct cpu_user_regs fault_regs;
+    struct cpu_user_regs fault_regs = *regs;
     struct extra_state fault_state;
     enum context context;
     struct vcpu *v = system_state >= SYS_STATE_smp_boot ? current : NULL;
 
-    /*
-     * Don't read beyond the end of the hardware frame.  It is out of bounds
-     * for WARN()/etc.
-     */
-    memcpy(&fault_regs, regs, offsetof(struct cpu_user_regs, es));
-
     if ( guest_mode(regs) && is_hvm_vcpu(v) )
     {
         get_hvm_registers(v, &fault_regs, &fault_state);