diff options
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/svm.c | 17 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 24 |
2 files changed, 20 insertions, 21 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index bc5b9b8d4a33..8a3f9f64f86f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -766,7 +766,6 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
766 | 766 | ||
767 | control->iopm_base_pa = iopm_base; | 767 | control->iopm_base_pa = iopm_base; |
768 | control->msrpm_base_pa = __pa(svm->msrpm); | 768 | control->msrpm_base_pa = __pa(svm->msrpm); |
769 | control->tsc_offset = 0; | ||
770 | control->int_ctl = V_INTR_MASKING_MASK; | 769 | control->int_ctl = V_INTR_MASKING_MASK; |
771 | 770 | ||
772 | init_seg(&save->es); | 771 | init_seg(&save->es); |
@@ -902,6 +901,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
902 | svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; | 901 | svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; |
903 | svm->asid_generation = 0; | 902 | svm->asid_generation = 0; |
904 | init_vmcb(svm); | 903 | init_vmcb(svm); |
904 | svm->vmcb->control.tsc_offset = 0-native_read_tsc(); | ||
905 | 905 | ||
906 | err = fx_init(&svm->vcpu); | 906 | err = fx_init(&svm->vcpu); |
907 | if (err) | 907 | if (err) |
@@ -3163,8 +3163,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
3163 | sync_lapic_to_cr8(vcpu); | 3163 | sync_lapic_to_cr8(vcpu); |
3164 | 3164 | ||
3165 | save_host_msrs(vcpu); | 3165 | save_host_msrs(vcpu); |
3166 | fs_selector = kvm_read_fs(); | 3166 | savesegment(fs, fs_selector); |
3167 | gs_selector = kvm_read_gs(); | 3167 | savesegment(gs, gs_selector); |
3168 | ldt_selector = kvm_read_ldt(); | 3168 | ldt_selector = kvm_read_ldt(); |
3169 | svm->vmcb->save.cr2 = vcpu->arch.cr2; | 3169 | svm->vmcb->save.cr2 = vcpu->arch.cr2; |
3170 | /* required for live migration with NPT */ | 3170 | /* required for live migration with NPT */ |
@@ -3251,10 +3251,15 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
3251 | vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; | 3251 | vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; |
3252 | vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; | 3252 | vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; |
3253 | 3253 | ||
3254 | kvm_load_fs(fs_selector); | ||
3255 | kvm_load_gs(gs_selector); | ||
3256 | kvm_load_ldt(ldt_selector); | ||
3257 | load_host_msrs(vcpu); | 3254 | load_host_msrs(vcpu); |
3255 | loadsegment(fs, fs_selector); | ||
3256 | #ifdef CONFIG_X86_64 | ||
3257 | load_gs_index(gs_selector); | ||
3258 | wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); | ||
3259 | #else | ||
3260 | loadsegment(gs, gs_selector); | ||
3261 | #endif | ||
3262 | kvm_load_ldt(ldt_selector); | ||
3258 | 3263 | ||
3259 | reload_tss(vcpu); | 3264 | reload_tss(vcpu); |
3260 | 3265 | ||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 49b25eee25ac..7bddfab12013 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -803,7 +803,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) | |||
803 | */ | 803 | */ |
804 | vmx->host_state.ldt_sel = kvm_read_ldt(); | 804 | vmx->host_state.ldt_sel = kvm_read_ldt(); |
805 | vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel; | 805 | vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel; |
806 | vmx->host_state.fs_sel = kvm_read_fs(); | 806 | savesegment(fs, vmx->host_state.fs_sel); |
807 | if (!(vmx->host_state.fs_sel & 7)) { | 807 | if (!(vmx->host_state.fs_sel & 7)) { |
808 | vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel); | 808 | vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel); |
809 | vmx->host_state.fs_reload_needed = 0; | 809 | vmx->host_state.fs_reload_needed = 0; |
@@ -811,7 +811,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) | |||
811 | vmcs_write16(HOST_FS_SELECTOR, 0); | 811 | vmcs_write16(HOST_FS_SELECTOR, 0); |
812 | vmx->host_state.fs_reload_needed = 1; | 812 | vmx->host_state.fs_reload_needed = 1; |
813 | } | 813 | } |
814 | vmx->host_state.gs_sel = kvm_read_gs(); | 814 | savesegment(gs, vmx->host_state.gs_sel); |
815 | if (!(vmx->host_state.gs_sel & 7)) | 815 | if (!(vmx->host_state.gs_sel & 7)) |
816 | vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel); | 816 | vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel); |
817 | else { | 817 | else { |
@@ -841,27 +841,21 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) | |||
841 | 841 | ||
842 | static void __vmx_load_host_state(struct vcpu_vmx *vmx) | 842 | static void __vmx_load_host_state(struct vcpu_vmx *vmx) |
843 | { | 843 | { |
844 | unsigned long flags; | ||
845 | |||
846 | if (!vmx->host_state.loaded) | 844 | if (!vmx->host_state.loaded) |
847 | return; | 845 | return; |
848 | 846 | ||
849 | ++vmx->vcpu.stat.host_state_reload; | 847 | ++vmx->vcpu.stat.host_state_reload; |
850 | vmx->host_state.loaded = 0; | 848 | vmx->host_state.loaded = 0; |
851 | if (vmx->host_state.fs_reload_needed) | 849 | if (vmx->host_state.fs_reload_needed) |
852 | kvm_load_fs(vmx->host_state.fs_sel); | 850 | loadsegment(fs, vmx->host_state.fs_sel); |
853 | if (vmx->host_state.gs_ldt_reload_needed) { | 851 | if (vmx->host_state.gs_ldt_reload_needed) { |
854 | kvm_load_ldt(vmx->host_state.ldt_sel); | 852 | kvm_load_ldt(vmx->host_state.ldt_sel); |
855 | /* | ||
856 | * If we have to reload gs, we must take care to | ||
857 | * preserve our gs base. | ||
858 | */ | ||
859 | local_irq_save(flags); | ||
860 | kvm_load_gs(vmx->host_state.gs_sel); | ||
861 | #ifdef CONFIG_X86_64 | 853 | #ifdef CONFIG_X86_64 |
862 | wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); | 854 | load_gs_index(vmx->host_state.gs_sel); |
855 | wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); | ||
856 | #else | ||
857 | loadsegment(gs, vmx->host_state.gs_sel); | ||
863 | #endif | 858 | #endif |
864 | local_irq_restore(flags); | ||
865 | } | 859 | } |
866 | reload_tss(); | 860 | reload_tss(); |
867 | #ifdef CONFIG_X86_64 | 861 | #ifdef CONFIG_X86_64 |
@@ -2589,8 +2583,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) | |||
2589 | vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ | 2583 | vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ |
2590 | vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ | 2584 | vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ |
2591 | vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ | 2585 | vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ |
2592 | vmcs_write16(HOST_FS_SELECTOR, kvm_read_fs()); /* 22.2.4 */ | 2586 | vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */ |
2593 | vmcs_write16(HOST_GS_SELECTOR, kvm_read_gs()); /* 22.2.4 */ | 2587 | vmcs_write16(HOST_GS_SELECTOR, 0); /* 22.2.4 */ |
2594 | vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ | 2588 | vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ |
2595 | #ifdef CONFIG_X86_64 | 2589 | #ifdef CONFIG_X86_64 |
2596 | rdmsrl(MSR_FS_BASE, a); | 2590 | rdmsrl(MSR_FS_BASE, a); |