mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
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 <andrew.cooper3@citrix.com>
This commit is contained in:
1 parent
9d967cb979
commit
ee653b97ce
4 files changed
+27
-29
No files matched your search
@@ -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) )
|
||||
{
|
||||
|
||||
+12
-14
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; \
|
||||
})
|
||||
|
||||
|
||||