diff options
author | Sean Christopherson <sean.j.christopherson@intel.com> | 2018-07-23 15:32:46 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-08-06 11:59:14 -0400 |
commit | e920de8507c6c8760c775cd718627e7cbf57c3b7 (patch) | |
tree | fd891fb14e3044f643a168b8aa619de2651e71ae | |
parent | fd1ec7723fbd560f924769b43cbdfe82dfd6a98e (diff) |
KVM: vmx: compute need to reload FS/GS/LDT on demand
Remove fs_reload_needed and gs_ldt_reload_needed from host_state
and instead compute whether we need to reload various state at
the time we actually do the reload. The state that is tracked
by the *_reload_needed variables is not any more volatile than
the trackers themselves.
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/vmx.c | 18 |
1 files changed, 5 insertions, 13 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a135c91d44f8..c8a583ff7bf2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -824,8 +824,6 @@ struct vcpu_vmx { | |||
824 | #ifdef CONFIG_X86_64 | 824 | #ifdef CONFIG_X86_64 |
825 | u16 ds_sel, es_sel; | 825 | u16 ds_sel, es_sel; |
826 | #endif | 826 | #endif |
827 | int gs_ldt_reload_needed; | ||
828 | int fs_reload_needed; | ||
829 | } host_state; | 827 | } host_state; |
830 | struct { | 828 | struct { |
831 | int vm86_active; | 829 | int vm86_active; |
@@ -2681,7 +2679,6 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) | |||
2681 | * allow segment selectors with cpl > 0 or ti == 1. | 2679 | * allow segment selectors with cpl > 0 or ti == 1. |
2682 | */ | 2680 | */ |
2683 | vmx->host_state.ldt_sel = kvm_read_ldt(); | 2681 | vmx->host_state.ldt_sel = kvm_read_ldt(); |
2684 | vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel; | ||
2685 | 2682 | ||
2686 | #ifdef CONFIG_X86_64 | 2683 | #ifdef CONFIG_X86_64 |
2687 | savesegment(ds, vmx->host_state.ds_sel); | 2684 | savesegment(ds, vmx->host_state.ds_sel); |
@@ -2711,20 +2708,15 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) | |||
2711 | #endif | 2708 | #endif |
2712 | 2709 | ||
2713 | vmx->host_state.fs_sel = fs_sel; | 2710 | vmx->host_state.fs_sel = fs_sel; |
2714 | if (!(fs_sel & 7)) { | 2711 | if (!(fs_sel & 7)) |
2715 | vmcs_write16(HOST_FS_SELECTOR, fs_sel); | 2712 | vmcs_write16(HOST_FS_SELECTOR, fs_sel); |
2716 | vmx->host_state.fs_reload_needed = 0; | 2713 | else |
2717 | } else { | ||
2718 | vmcs_write16(HOST_FS_SELECTOR, 0); | 2714 | vmcs_write16(HOST_FS_SELECTOR, 0); |
2719 | vmx->host_state.fs_reload_needed = 1; | ||
2720 | } | ||
2721 | vmx->host_state.gs_sel = gs_sel; | 2715 | vmx->host_state.gs_sel = gs_sel; |
2722 | if (!(gs_sel & 7)) | 2716 | if (!(gs_sel & 7)) |
2723 | vmcs_write16(HOST_GS_SELECTOR, gs_sel); | 2717 | vmcs_write16(HOST_GS_SELECTOR, gs_sel); |
2724 | else { | 2718 | else |
2725 | vmcs_write16(HOST_GS_SELECTOR, 0); | 2719 | vmcs_write16(HOST_GS_SELECTOR, 0); |
2726 | vmx->host_state.gs_ldt_reload_needed = 1; | ||
2727 | } | ||
2728 | 2720 | ||
2729 | vmcs_writel(HOST_FS_BASE, fs_base); | 2721 | vmcs_writel(HOST_FS_BASE, fs_base); |
2730 | vmcs_writel(HOST_GS_BASE, gs_base); | 2722 | vmcs_writel(HOST_GS_BASE, gs_base); |
@@ -2749,7 +2741,7 @@ static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx) | |||
2749 | if (is_long_mode(&vmx->vcpu)) | 2741 | if (is_long_mode(&vmx->vcpu)) |
2750 | rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); | 2742 | rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); |
2751 | #endif | 2743 | #endif |
2752 | if (vmx->host_state.gs_ldt_reload_needed) { | 2744 | if (vmx->host_state.ldt_sel || (vmx->host_state.gs_sel & 7)) { |
2753 | kvm_load_ldt(vmx->host_state.ldt_sel); | 2745 | kvm_load_ldt(vmx->host_state.ldt_sel); |
2754 | #ifdef CONFIG_X86_64 | 2746 | #ifdef CONFIG_X86_64 |
2755 | load_gs_index(vmx->host_state.gs_sel); | 2747 | load_gs_index(vmx->host_state.gs_sel); |
@@ -2757,7 +2749,7 @@ static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx) | |||
2757 | loadsegment(gs, vmx->host_state.gs_sel); | 2749 | loadsegment(gs, vmx->host_state.gs_sel); |
2758 | #endif | 2750 | #endif |
2759 | } | 2751 | } |
2760 | if (vmx->host_state.fs_reload_needed) | 2752 | if (vmx->host_state.fs_sel & 7) |
2761 | loadsegment(fs, vmx->host_state.fs_sel); | 2753 | loadsegment(fs, vmx->host_state.fs_sel); |
2762 | #ifdef CONFIG_X86_64 | 2754 | #ifdef CONFIG_X86_64 |
2763 | if (unlikely(vmx->host_state.ds_sel | vmx->host_state.es_sel)) { | 2755 | if (unlikely(vmx->host_state.ds_sel | vmx->host_state.es_sel)) { |