From: Andrew Cooper Date: Wed, 14 Oct 2015 10:48:36 +0000 (+0200) Subject: x86/traps: don't use 16bit reads of segment registers X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=ee653b97ce369decfdd4d18979fd9f6aec0073c2;p=people%2Froyger%2Fxen.git x86/traps: don't use 16bit reads of segment registers 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 --- diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 91c04f8360..fe3be30a62 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -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) ) { diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index f1fc7b79d5..80935358bf 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -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: diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 0846a19395..b7c275978c 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -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); diff --git a/xen/include/asm-x86/system.h b/xen/include/asm-x86/system.h index 9fb70f5704..eb498f5e71 100644 --- a/xen/include/asm-x86/system.h +++ b/xen/include/asm-x86/system.h @@ -5,9 +5,9 @@ #include #include -#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; \ })