]> xenbits.xensource.com Git - people/julieng/xen-unstable.git/commitdiff
x86/traps: don't use 16bit reads of segment registers
authorAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 14 Oct 2015 10:48:36 +0000 (12:48 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 14 Oct 2015 10:48:36 +0000 (12:48 +0200)
When executing `mov %sreg, %r32`, older Intel processors would leave the
upper 16 bits of %r32 undefined.  P4 processors and newer, as well as
all AMD processors will zero extend the segment selector.

As Xen only supports 64bit these days, there is no need to use the
operand-size override prefix and suffer the resulting pipeline overhead.

Rename read_segment_register() to read_sreg() and drop the existing
read_sreg() wrapper which took a regs parameter and did nothing with it.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/domain.c
xen/arch/x86/traps.c
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/system.h

index 91c04f8360d16dd6b4a5709e66f9eee734b20e00..fe3be30a62a8b481d1329a8c3c6880e3dc766826 100644 (file)
@@ -1412,10 +1412,10 @@ static void save_segments(struct vcpu *v)
     struct cpu_user_regs *regs = &v->arch.user_regs;
     unsigned int dirty_segment_mask = 0;
 
-    regs->ds = read_segment_register(ds);
-    regs->es = read_segment_register(es);
-    regs->fs = read_segment_register(fs);
-    regs->gs = read_segment_register(gs);
+    regs->ds = read_sreg(ds);
+    regs->es = read_sreg(es);
+    regs->fs = read_sreg(fs);
+    regs->gs = read_sreg(gs);
 
     if ( cpu_has_fsgsbase && !is_pv_32bit_vcpu(v) )
     {
index f1fc7b79d51507318dffe8e7410d4ab400989f6e..80935358bf7a82211d6882756723296138444c92 100644 (file)
@@ -1981,8 +1981,6 @@ static inline uint64_t guest_misc_enable(uint64_t val)
     }                                                                       \
     (eip) += sizeof(_x); _x; })
 
-#define read_sreg(regs, sr) read_segment_register(sr)
-
 static int is_cpufreq_controller(struct domain *d)
 {
     return ((cpufreq_controller == FREQCTL_dom0_kernel) &&
@@ -2029,7 +2027,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
         goto fail;
 
     /* emulating only opcodes not allowing SS to be default */
-    data_sel = read_sreg(regs, ds);
+    data_sel = read_sreg(ds);
 
     /* Legacy prefixes. */
     for ( i = 0; i < 8; i++, rex == opcode || (rex = 0) )
@@ -2047,17 +2045,17 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
             data_sel = regs->cs;
             continue;
         case 0x3e: /* DS override */
-            data_sel = read_sreg(regs, ds);
+            data_sel = read_sreg(ds);
             continue;
         case 0x26: /* ES override */
-            data_sel = read_sreg(regs, es);
+            data_sel = read_sreg(es);
             continue;
         case 0x64: /* FS override */
-            data_sel = read_sreg(regs, fs);
+            data_sel = read_sreg(fs);
             lm_ovr = lm_seg_fs;
             continue;
         case 0x65: /* GS override */
-            data_sel = read_sreg(regs, gs);
+            data_sel = read_sreg(gs);
             lm_ovr = lm_seg_gs;
             continue;
         case 0x36: /* SS override */
@@ -2104,7 +2102,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
 
         if ( !(opcode & 2) )
         {
-            data_sel = read_sreg(regs, es);
+            data_sel = read_sreg(es);
             lm_ovr = lm_seg_none;
         }
 
@@ -2912,22 +2910,22 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
             ASSERT(opnd_sel);
             continue;
         case 0x3e: /* DS override */
-            opnd_sel = read_sreg(regs, ds);
+            opnd_sel = read_sreg(ds);
             if ( !opnd_sel )
                 opnd_sel = dpl;
             continue;
         case 0x26: /* ES override */
-            opnd_sel = read_sreg(regs, es);
+            opnd_sel = read_sreg(es);
             if ( !opnd_sel )
                 opnd_sel = dpl;
             continue;
         case 0x64: /* FS override */
-            opnd_sel = read_sreg(regs, fs);
+            opnd_sel = read_sreg(fs);
             if ( !opnd_sel )
                 opnd_sel = dpl;
             continue;
         case 0x65: /* GS override */
-            opnd_sel = read_sreg(regs, gs);
+            opnd_sel = read_sreg(gs);
             if ( !opnd_sel )
                 opnd_sel = dpl;
             continue;
@@ -2980,7 +2978,7 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
                             switch ( modrm & 7 )
                             {
                             default:
-                                opnd_sel = read_sreg(regs, ds);
+                                opnd_sel = read_sreg(ds);
                                 break;
                             case 4: case 5:
                                 opnd_sel = regs->ss;
@@ -3008,7 +3006,7 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
                             break;
                         }
                         if ( !opnd_sel )
-                            opnd_sel = read_sreg(regs, ds);
+                            opnd_sel = read_sreg(ds);
                         switch ( modrm & 7 )
                         {
                         case 0: case 2: case 4:
index 0846a19395ec98a7e11900458a661b0b28e7b347..b7c275978c413f8531525d381715824bc111f773 100644 (file)
@@ -125,10 +125,10 @@ void show_registers(const struct cpu_user_regs *regs)
         fault_crs[0] = read_cr0();
         fault_crs[3] = read_cr3();
         fault_crs[4] = read_cr4();
-        fault_regs.ds = read_segment_register(ds);
-        fault_regs.es = read_segment_register(es);
-        fault_regs.fs = read_segment_register(fs);
-        fault_regs.gs = read_segment_register(gs);
+        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();
@@ -242,10 +242,10 @@ void do_double_fault(struct cpu_user_regs *regs)
     crs[2] = read_cr2();
     crs[3] = read_cr3();
     crs[4] = read_cr4();
-    regs->ds = read_segment_register(ds);
-    regs->es = read_segment_register(es);
-    regs->fs = read_segment_register(fs);
-    regs->gs = read_segment_register(gs);
+    regs->ds = read_sreg(ds);
+    regs->es = read_sreg(es);
+    regs->fs = read_sreg(fs);
+    regs->gs = read_sreg(gs);
 
     printk("CPU:    %d\n", cpu);
     _show_registers(regs, crs, CTXT_hypervisor, NULL);
index 9fb70f570482ada69f0676a47bc528008cd6caa1..eb498f5e71b273e0fc1c918f035bfd50438c434f 100644 (file)
@@ -5,9 +5,9 @@
 #include <xen/bitops.h>
 #include <asm/processor.h>
 
-#define read_segment_register(name)                             \
-({  u16 __sel;                                                  \
-    asm volatile ( "movw %%" STR(name) ",%0" : "=r" (__sel) );  \
+#define read_sreg(name)                                         \
+({  unsigned int __sel;                                         \
+    asm volatile ( "mov %%" STR(name) ",%0" : "=r" (__sel) );   \
     __sel;                                                      \
 })