... in preference to the crs[8] array.  This avoids abusing crs[5..7] for the
fs/gs bases, giving them proper named fields instead, and avoids storage for
cr1 which is unused in the x86 architecture.

In show_registers(), remove a redundant read_cr2().  read_registers() already
did the same, and it is only the PV path which needs to override with
arch_get_cr2().

In vcpu_show_registers(), express the gsb/gss decision using SWAP().  The
determination is going to get even more complicated under FRED.

No functional change.

Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com>
---
CC: Jan Beulich <jbeul...@suse.com>
CC: Roger Pau Monné <roger....@citrix.com>
---
 xen/arch/x86/x86_64/traps.c | 96 +++++++++++++++++++++----------------
 1 file changed, 54 insertions(+), 42 deletions(-)

diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index ac0fafd72d31..01b4f0623282 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -23,6 +23,11 @@
 #include <asm/shared.h>
 #include <asm/traps.h>
 
+struct extra_state
+{
+    unsigned long cr0, cr2, cr3, cr4;
+    unsigned long fsb, gsb, gss;
+};
 
 static void print_xen_info(void)
 {
@@ -35,28 +40,29 @@ static void print_xen_info(void)
 
 enum context { CTXT_hypervisor, CTXT_pv_guest, CTXT_hvm_guest };
 
-/* (ab)use crs[5..7] for fs/gs bases. */
-static void read_registers(struct cpu_user_regs *regs, unsigned long crs[8])
+static void read_registers(struct cpu_user_regs *regs, struct extra_state 
*state)
 {
-    crs[0] = read_cr0();
-    crs[2] = read_cr2();
-    crs[3] = read_cr3();
-    crs[4] = read_cr4();
+    state->cr0 = read_cr0();
+    state->cr2 = read_cr2();
+    state->cr3 = read_cr3();
+    state->cr4 = read_cr4();
+
     read_sregs(regs);
-    crs[5] = read_fs_base();
-    crs[6] = read_gs_base();
-    crs[7] = read_gs_shadow();
+
+    state->fsb = read_fs_base();
+    state->gsb = read_gs_base();
+    state->gss = read_gs_shadow();
 }
 
 static void get_hvm_registers(struct vcpu *v, struct cpu_user_regs *regs,
-                              unsigned long crs[8])
+                              struct extra_state *state)
 {
     struct segment_register sreg;
 
-    crs[0] = v->arch.hvm.guest_cr[0];
-    crs[2] = v->arch.hvm.guest_cr[2];
-    crs[3] = v->arch.hvm.guest_cr[3];
-    crs[4] = v->arch.hvm.guest_cr[4];
+    state->cr0 = v->arch.hvm.guest_cr[0];
+    state->cr2 = v->arch.hvm.guest_cr[2];
+    state->cr3 = v->arch.hvm.guest_cr[3];
+    state->cr4 = v->arch.hvm.guest_cr[4];
 
     hvm_get_segment_register(v, x86_seg_cs, &sreg);
     regs->cs = sreg.sel;
@@ -69,20 +75,20 @@ static void get_hvm_registers(struct vcpu *v, struct 
cpu_user_regs *regs,
 
     hvm_get_segment_register(v, x86_seg_fs, &sreg);
     regs->fs = sreg.sel;
-    crs[5] = sreg.base;
+    state->fsb = sreg.base;
 
     hvm_get_segment_register(v, x86_seg_gs, &sreg);
     regs->gs = sreg.sel;
-    crs[6] = sreg.base;
+    state->gsb = sreg.base;
 
     hvm_get_segment_register(v, x86_seg_ss, &sreg);
     regs->ss = sreg.sel;
 
-    crs[7] = hvm_get_reg(v, MSR_SHADOW_GS_BASE);
+    state->gss = hvm_get_reg(v, MSR_SHADOW_GS_BASE);
 }
 
 static void _show_registers(
-    const struct cpu_user_regs *regs, unsigned long crs[8],
+    const struct cpu_user_regs *regs, const struct extra_state *state,
     enum context context, const struct vcpu *v)
 {
     static const char *const context_names[] = {
@@ -112,10 +118,10 @@ static void _show_registers(
     printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
            regs->r12, regs->r13, regs->r14);
     printk("r15: %016lx   cr0: %016lx   cr4: %016lx\n",
-           regs->r15, crs[0], crs[4]);
-    printk("cr3: %016lx   cr2: %016lx\n", crs[3], crs[2]);
+           regs->r15, state->cr0, state->cr4);
+    printk("cr3: %016lx   cr2: %016lx\n", state->cr3, state->cr2);
     printk("fsb: %016lx   gsb: %016lx   gss: %016lx\n",
-           crs[5], crs[6], crs[7]);
+           state->fsb, state->gsb, state->gss);
     printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
            "ss: %04x   cs: %04x\n",
            regs->ds, regs->es, regs->fs,
@@ -125,34 +131,33 @@ static void _show_registers(
 void show_registers(const struct cpu_user_regs *regs)
 {
     struct cpu_user_regs fault_regs = *regs;
-    unsigned long fault_crs[8];
+    struct extra_state fault_state;
     enum context context;
     struct vcpu *v = system_state >= SYS_STATE_smp_boot ? current : NULL;
 
     if ( guest_mode(regs) && is_hvm_vcpu(v) )
     {
-        get_hvm_registers(v, &fault_regs, fault_crs);
+        get_hvm_registers(v, &fault_regs, &fault_state);
         context = CTXT_hvm_guest;
     }
     else
     {
-        read_registers(&fault_regs, fault_crs);
+        read_registers(&fault_regs, &fault_state);
 
         if ( guest_mode(regs) )
         {
             context = CTXT_pv_guest;
-            fault_crs[2] = arch_get_cr2(v);
+            fault_state.cr2 = arch_get_cr2(v);
         }
         else
         {
             context = CTXT_hypervisor;
-            fault_crs[2] = read_cr2();
         }
     }
 
     print_xen_info();
     printk("CPU:    %d\n", smp_processor_id());
-    _show_registers(&fault_regs, fault_crs, context, v);
+    _show_registers(&fault_regs, &fault_state, context, v);
 
     if ( ler_msr && !guest_mode(regs) )
     {
@@ -173,34 +178,41 @@ void vcpu_show_registers(struct vcpu *v)
 {
     const struct cpu_user_regs *regs = &v->arch.user_regs;
     struct cpu_user_regs aux_regs;
+    struct extra_state state;
     enum context context;
-    unsigned long crs[8];
 
     if ( is_hvm_vcpu(v) )
     {
         aux_regs = *regs;
-        get_hvm_registers(v, &aux_regs, crs);
+        get_hvm_registers(v, &aux_regs, &state);
         regs = &aux_regs;
         context = CTXT_hvm_guest;
     }
     else
     {
         bool kernel = guest_kernel_mode(v, regs);
+        unsigned long gsb, gss;
+
+        state.cr0 = v->arch.pv.ctrlreg[0];
+        state.cr2 = arch_get_cr2(v);
+        state.cr3 = pagetable_get_paddr(kernel
+                                        ? v->arch.guest_table
+                                        : v->arch.guest_table_user);
+        state.cr4 = v->arch.pv.ctrlreg[4];
+
+        gsb = v->arch.pv.gs_base_user;
+        gss = v->arch.pv.gs_base_kernel;
+        if ( kernel )
+            SWAP(gsb, gss);
 
-        crs[0] = v->arch.pv.ctrlreg[0];
-        crs[2] = arch_get_cr2(v);
-        crs[3] = pagetable_get_paddr(kernel ?
-                                     v->arch.guest_table :
-                                     v->arch.guest_table_user);
-        crs[4] = v->arch.pv.ctrlreg[4];
-        crs[5] = v->arch.pv.fs_base;
-        crs[6 + !kernel] = v->arch.pv.gs_base_kernel;
-        crs[7 - !kernel] = v->arch.pv.gs_base_user;
+        state.fsb = v->arch.pv.fs_base;
+        state.gsb = gsb;
+        state.gss = gss;
 
         context = CTXT_pv_guest;
     }
 
-    _show_registers(regs, crs, context, v);
+    _show_registers(regs, &state, context, v);
 }
 
 void show_page_walk(unsigned long addr)
@@ -268,7 +280,7 @@ void show_page_walk(unsigned long addr)
 void asmlinkage do_double_fault(struct cpu_user_regs *regs)
 {
     unsigned int cpu;
-    unsigned long crs[8];
+    struct extra_state state;
 
     console_force_unlock();
 
@@ -279,10 +291,10 @@ void asmlinkage do_double_fault(struct cpu_user_regs 
*regs)
     printk("*** DOUBLE FAULT ***\n");
     print_xen_info();
 
-    read_registers(regs, crs);
+    read_registers(regs, &state);
 
     printk("CPU:    %d\n", cpu);
-    _show_registers(regs, crs, CTXT_hypervisor, NULL);
+    _show_registers(regs, &state, CTXT_hypervisor, NULL);
     show_code(regs);
     show_stack_overflow(cpu, regs);
 
-- 
2.39.5


Reply via email to