diff options
Diffstat (limited to 'xen/arch/x86')
-rw-r--r-- | xen/arch/x86/Rules.mk | 1 | ||||
-rw-r--r-- | xen/arch/x86/acpi/suspend.c | 8 | ||||
-rw-r--r-- | xen/arch/x86/domain.c | 4 | ||||
-rw-r--r-- | xen/arch/x86/setup.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 30 |
5 files changed, 20 insertions, 26 deletions
diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk index c93d2affd3..576985e710 100644 --- a/xen/arch/x86/Rules.mk +++ b/xen/arch/x86/Rules.mk @@ -31,6 +31,7 @@ $(call cc-options-add,CFLAGS,CC,$(EMBEDDED_EXTRA_CFLAGS)) $(call cc-option-add,CFLAGS,CC,-Wnested-externs) $(call as-insn-check,CFLAGS,CC,"vmcall",-DHAVE_GAS_VMX) $(call as-insn-check,CFLAGS,CC,"invept (%rax)$$(comma)%rax",-DHAVE_GAS_EPT) +$(call as-insn-check,CFLAGS,CC,"rdfsbase %rax",-DHAVE_GAS_FSGSBASE) ifeq ($(supervisor_mode_kernel),y) CFLAGS += -DCONFIG_X86_SUPERVISOR_MODE_KERNEL=1 diff --git a/xen/arch/x86/acpi/suspend.c b/xen/arch/x86/acpi/suspend.c index c690b45345..9c3cf38fe5 100644 --- a/xen/arch/x86/acpi/suspend.c +++ b/xen/arch/x86/acpi/suspend.c @@ -27,8 +27,8 @@ void save_rest_processor_state(void) asm volatile ( "movw %%ds,(%0); movw %%es,2(%0); movw %%fs,4(%0); movw %%gs,6(%0)" : : "r" (saved_segs) : "memory" ); - rdmsrl(MSR_FS_BASE, saved_fs_base); - rdmsrl(MSR_GS_BASE, saved_gs_base); + saved_fs_base = rdfsbase(); + saved_gs_base = rdgsbase(); rdmsrl(MSR_SHADOW_GS_BASE, saved_kernel_gs_base); rdmsrl(MSR_CSTAR, saved_cstar); rdmsrl(MSR_LSTAR, saved_lstar); @@ -56,8 +56,8 @@ void restore_rest_processor_state(void) X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_TF, 0U); - wrmsrl(MSR_FS_BASE, saved_fs_base); - wrmsrl(MSR_GS_BASE, saved_gs_base); + wrfsbase(saved_fs_base); + wrgsbase(saved_gs_base); wrmsrl(MSR_SHADOW_GS_BASE, saved_kernel_gs_base); if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL || diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 52b7a37fec..b67fcb8f78 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1092,7 +1092,7 @@ static void load_segments(struct vcpu *n) { /* This can only be non-zero if selector is NULL. */ if ( n->arch.pv_vcpu.fs_base ) - wrmsrl(MSR_FS_BASE, n->arch.pv_vcpu.fs_base); + wrfsbase(n->arch.pv_vcpu.fs_base); /* Most kernels have non-zero GS base, so don't bother testing. */ /* (This is also a serialising instruction, avoiding AMD erratum #88.) */ @@ -1100,7 +1100,7 @@ static void load_segments(struct vcpu *n) /* This can only be non-zero if selector is NULL. */ if ( n->arch.pv_vcpu.gs_base_user ) - wrmsrl(MSR_GS_BASE, n->arch.pv_vcpu.gs_base_user); + wrgsbase(n->arch.pv_vcpu.gs_base_user); /* If in kernel mode then switch the GS bases around. */ if ( (n->arch.flags & TF_kernel_mode) ) diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 637f1f97f8..30a4fd6b88 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1264,6 +1264,9 @@ void __init __start_xen(unsigned long mbi_p) if ( cpu_has_smep ) set_in_cr4(X86_CR4_SMEP); + if ( cpu_has_fsgsbase ) + set_in_cr4(X86_CR4_FSGSBASE); + local_irq_enable(); pt_pci_init(); diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 35be017dc8..8dcb70a98f 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1985,28 +1985,18 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) } else { - if ( lm_ovr == lm_seg_none || data_sel < 4 ) + switch ( lm_ovr ) { - switch ( lm_ovr ) - { - case lm_seg_none: - data_base = 0UL; - break; - case lm_seg_fs: - data_base = v->arch.pv_vcpu.fs_base; - break; - case lm_seg_gs: - if ( guest_kernel_mode(v, regs) ) - data_base = v->arch.pv_vcpu.gs_base_kernel; - else - data_base = v->arch.pv_vcpu.gs_base_user; - break; - } + default: + data_base = 0UL; + break; + case lm_seg_fs: + data_base = rdfsbase(); + break; + case lm_seg_gs: + data_base = rdgsbase(); + break; } - else if ( !read_descriptor(data_sel, v, regs, - &data_base, &data_limit, &ar, 0) || - !(ar & _SEGMENT_S) || !(ar & _SEGMENT_P) ) - goto fail; data_limit = ~0UL; ar = _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P; } |