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

[PATCH v2 4/4] x86: Drop the vm86 segments selectors from struct cpu_user_regs



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@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
 xen/arch/x86/cpu/common.c                | 2 +-
 xen/arch/x86/include/asm/cpu-user-regs.h | 5 -----
 xen/arch/x86/include/asm/current.h       | 8 ++++----
 xen/arch/x86/include/asm/hvm/hvm.h       | 4 ----
 xen/arch/x86/include/asm/regs.h          | 3 +--
 xen/arch/x86/traps.c                     | 2 +-
 xen/arch/x86/x86_64/asm-offsets.c        | 2 +-
 xen/arch/x86/x86_64/traps.c              | 8 +-------
 8 files changed, 9 insertions(+), 25 deletions(-)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index e063fe790a97..97bdda1d4a25 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -959,7 +959,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));
 }
 
diff --git a/xen/arch/x86/include/asm/cpu-user-regs.h 
b/xen/arch/x86/include/asm/cpu-user-regs.h
index 0e78e38ed00d..d700a3ef3447 100644
--- a/xen/arch/x86/include/asm/cpu-user-regs.h
+++ b/xen/arch/x86/include/asm/cpu-user-regs.h
@@ -53,11 +53,6 @@ struct cpu_user_regs
      * For IDT delivery, tss->rsp0 points to this boundary as embedded within
      * struct cpu_info.  It must be 16-byte aligned.
      */
-
-    uint16_t es, _pad3[3];
-    uint16_t ds, _pad4[3];
-    uint16_t fs, _pad5[3];
-    uint16_t gs, _pad6[3];
 };
 
 #endif /* X86_CPU_USER_REGS_H */
diff --git a/xen/arch/x86/include/asm/current.h 
b/xen/arch/x86/include/asm/current.h
index 243d17ef79fd..a7c9473428b2 100644
--- a/xen/arch/x86/include/asm/current.h
+++ b/xen/arch/x86/include/asm/current.h
@@ -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
diff --git a/xen/arch/x86/include/asm/hvm/hvm.h 
b/xen/arch/x86/include/asm/hvm/hvm.h
index bf8bc2e100bd..18e40910ff71 100644
--- a/xen/arch/x86/include/asm/hvm/hvm.h
+++ b/xen/arch/x86/include/asm/hvm/hvm.h
@@ -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
 }
 
diff --git a/xen/arch/x86/include/asm/regs.h b/xen/arch/x86/include/asm/regs.h
index ce9b028276a1..72595110e2d5 100644
--- a/xen/arch/x86/include/asm/regs.h
+++ b/xen/arch/x86/include/asm/regs.h
@@ -23,8 +23,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)                                                         \
 ({                                                                            \
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 34dc077cad34..238d923dd188 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -387,7 +387,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) -
diff --git a/xen/arch/x86/x86_64/asm-offsets.c 
b/xen/arch/x86/x86_64/asm-offsets.c
index 630bdc39451d..2258b4ce1b95 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -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();
 
     /*
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index 29ac5a14ca3f..34adf55e48df 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -135,17 +135,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);
-- 
2.39.5




 


Rackspace

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