[xen stable-4.7] x86: also show FS/GS base addresses when dumping registers

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen stable-4.7] x86: also show FS/GS base addresses when dumping registers

patchbot
commit a27ed6a9bf0ac7fb4768c8e7234411ebbb0d090b
Author:     Jan Beulich <[hidden email]>
AuthorDate: Thu Nov 16 11:58:47 2017 +0100
Commit:     Jan Beulich <[hidden email]>
CommitDate: Thu Nov 16 11:58:47 2017 +0100

    x86: also show FS/GS base addresses when dumping registers
   
    Their state may be important to figure the reason for a crash. To not
    further grow duplicate code, break out a helper function.
   
    I realize that (ab)using the control register array here may not be
    considered the nicest solution, but it seems easier (and less overall
    overhead) to do so compared to the alternative of introducing another
    helper structure.
   
    Signed-off-by: Jan Beulich <[hidden email]>
    Reviewed-by Andrew Cooper <[hidden email]>
    master commit: be7f60b5a39741eab0a8fea0324f7be0cb724cfb
    master date: 2017-10-24 18:13:13 +0200
---
 xen/arch/x86/x86_64/traps.c | 46 ++++++++++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index 5b71537..a379d19 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -37,6 +37,22 @@ 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])
+{
+    crs[0] = read_cr0();
+    crs[2] = read_cr2();
+    crs[3] = read_cr3();
+    crs[4] = read_cr4();
+    regs->ds = read_sreg(ds);
+    regs->es = read_sreg(es);
+    regs->fs = read_sreg(fs);
+    regs->gs = read_sreg(gs);
+    crs[5] = rdfsbase();
+    crs[6] = rdgsbase();
+    rdmsrl(MSR_SHADOW_GS_BASE, crs[7]);
+}
+
 static void _show_registers(
     const struct cpu_user_regs *regs, unsigned long crs[8],
     enum context context, const struct vcpu *v)
@@ -75,6 +91,8 @@ static void _show_registers(
     else
         printk("cr0: %016lx   cr4: %016lx\n", crs[0], crs[4]);
     printk("cr3: %016lx   cr2: %016lx\n", crs[3], crs[2]);
+    printk("fsb: %016lx   gsb: %016lx   gss: %016lx\n",
+           crs[5], crs[6], crs[7]);
     printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
            "ss: %04x   cs: %04x\n",
            regs->ds, regs->es, regs->fs,
@@ -104,13 +122,18 @@ void show_registers(const struct cpu_user_regs *regs)
         fault_regs.es = sreg.sel;
         hvm_get_segment_register(v, x86_seg_fs, &sreg);
         fault_regs.fs = sreg.sel;
+        fault_crs[5] = sreg.base;
         hvm_get_segment_register(v, x86_seg_gs, &sreg);
         fault_regs.gs = sreg.sel;
+        fault_crs[6] = sreg.base;
         hvm_get_segment_register(v, x86_seg_ss, &sreg);
         fault_regs.ss = sreg.sel;
+        fault_crs[7] = hvm_get_shadow_gs_base(v);
     }
     else
     {
+        read_registers(&fault_regs, fault_crs);
+
         if ( guest_mode(regs) )
         {
             context = CTXT_pv_guest;
@@ -121,14 +144,6 @@ void show_registers(const struct cpu_user_regs *regs)
             context = CTXT_hypervisor;
             fault_crs[2] = read_cr2();
         }
-
-        fault_crs[0] = read_cr0();
-        fault_crs[3] = read_cr3();
-        fault_crs[4] = read_cr4();
-        fault_regs.ds = read_sreg(ds);
-        fault_regs.es = read_sreg(es);
-        fault_regs.fs = read_sreg(fs);
-        fault_regs.gs = read_sreg(gs);
     }
 
     print_xen_info();
@@ -147,6 +162,7 @@ void show_registers(const struct cpu_user_regs *regs)
 void vcpu_show_registers(const struct vcpu *v)
 {
     const struct cpu_user_regs *regs = &v->arch.user_regs;
+    bool_t kernel = guest_kernel_mode(v, regs);
     unsigned long crs[8];
 
     /* Only handle PV guests for now */
@@ -155,10 +171,13 @@ void vcpu_show_registers(const struct vcpu *v)
 
     crs[0] = v->arch.pv_vcpu.ctrlreg[0];
     crs[2] = arch_get_cr2(v);
-    crs[3] = pagetable_get_paddr(guest_kernel_mode(v, regs) ?
+    crs[3] = pagetable_get_paddr(kernel ?
                                  v->arch.guest_table :
                                  v->arch.guest_table_user);
     crs[4] = v->arch.pv_vcpu.ctrlreg[4];
+    crs[5] = v->arch.pv_vcpu.fs_base;
+    crs[6 + !kernel] = v->arch.pv_vcpu.gs_base_kernel;
+    crs[7 - !kernel] = v->arch.pv_vcpu.gs_base_user;
 
     _show_registers(regs, crs, CTXT_pv_guest, v);
 }
@@ -238,14 +257,7 @@ void do_double_fault(struct cpu_user_regs *regs)
     printk("*** DOUBLE FAULT ***\n");
     print_xen_info();
 
-    crs[0] = read_cr0();
-    crs[2] = read_cr2();
-    crs[3] = read_cr3();
-    crs[4] = read_cr4();
-    regs->ds = read_sreg(ds);
-    regs->es = read_sreg(es);
-    regs->fs = read_sreg(fs);
-    regs->gs = read_sreg(gs);
+    read_registers(regs, crs);
 
     printk("CPU:    %d\n", cpu);
     _show_registers(regs, crs, CTXT_hypervisor, NULL);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.7

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog