diff options
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 219 |
1 files changed, 102 insertions, 117 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 7bddfab12013..8da0e45ff7c9 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * machines without emulation or binary translation. | 5 | * machines without emulation or binary translation. |
6 | * | 6 | * |
7 | * Copyright (C) 2006 Qumranet, Inc. | 7 | * Copyright (C) 2006 Qumranet, Inc. |
8 | * Copyright 2010 Red Hat, Inc. and/or its affilates. | 8 | * Copyright 2010 Red Hat, Inc. and/or its affiliates. |
9 | * | 9 | * |
10 | * Authors: | 10 | * Authors: |
11 | * Avi Kivity <avi@qumranet.com> | 11 | * Avi Kivity <avi@qumranet.com> |
@@ -125,6 +125,7 @@ struct vcpu_vmx { | |||
125 | unsigned long host_rsp; | 125 | unsigned long host_rsp; |
126 | int launched; | 126 | int launched; |
127 | u8 fail; | 127 | u8 fail; |
128 | u32 exit_intr_info; | ||
128 | u32 idt_vectoring_info; | 129 | u32 idt_vectoring_info; |
129 | struct shared_msr_entry *guest_msrs; | 130 | struct shared_msr_entry *guest_msrs; |
130 | int nmsrs; | 131 | int nmsrs; |
@@ -154,11 +155,6 @@ struct vcpu_vmx { | |||
154 | u32 limit; | 155 | u32 limit; |
155 | u32 ar; | 156 | u32 ar; |
156 | } tr, es, ds, fs, gs; | 157 | } tr, es, ds, fs, gs; |
157 | struct { | ||
158 | bool pending; | ||
159 | u8 vector; | ||
160 | unsigned rip; | ||
161 | } irq; | ||
162 | } rmode; | 158 | } rmode; |
163 | int vpid; | 159 | int vpid; |
164 | bool emulation_required; | 160 | bool emulation_required; |
@@ -505,7 +501,6 @@ static void __vcpu_clear(void *arg) | |||
505 | vmcs_clear(vmx->vmcs); | 501 | vmcs_clear(vmx->vmcs); |
506 | if (per_cpu(current_vmcs, cpu) == vmx->vmcs) | 502 | if (per_cpu(current_vmcs, cpu) == vmx->vmcs) |
507 | per_cpu(current_vmcs, cpu) = NULL; | 503 | per_cpu(current_vmcs, cpu) = NULL; |
508 | rdtscll(vmx->vcpu.arch.host_tsc); | ||
509 | list_del(&vmx->local_vcpus_link); | 504 | list_del(&vmx->local_vcpus_link); |
510 | vmx->vcpu.cpu = -1; | 505 | vmx->vcpu.cpu = -1; |
511 | vmx->launched = 0; | 506 | vmx->launched = 0; |
@@ -706,11 +701,10 @@ static void reload_tss(void) | |||
706 | /* | 701 | /* |
707 | * VT restores TR but not its size. Useless. | 702 | * VT restores TR but not its size. Useless. |
708 | */ | 703 | */ |
709 | struct desc_ptr gdt; | 704 | struct desc_ptr *gdt = &__get_cpu_var(host_gdt); |
710 | struct desc_struct *descs; | 705 | struct desc_struct *descs; |
711 | 706 | ||
712 | native_store_gdt(&gdt); | 707 | descs = (void *)gdt->address; |
713 | descs = (void *)gdt.address; | ||
714 | descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ | 708 | descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ |
715 | load_TR_desc(); | 709 | load_TR_desc(); |
716 | } | 710 | } |
@@ -753,7 +747,7 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) | |||
753 | 747 | ||
754 | static unsigned long segment_base(u16 selector) | 748 | static unsigned long segment_base(u16 selector) |
755 | { | 749 | { |
756 | struct desc_ptr gdt; | 750 | struct desc_ptr *gdt = &__get_cpu_var(host_gdt); |
757 | struct desc_struct *d; | 751 | struct desc_struct *d; |
758 | unsigned long table_base; | 752 | unsigned long table_base; |
759 | unsigned long v; | 753 | unsigned long v; |
@@ -761,8 +755,7 @@ static unsigned long segment_base(u16 selector) | |||
761 | if (!(selector & ~3)) | 755 | if (!(selector & ~3)) |
762 | return 0; | 756 | return 0; |
763 | 757 | ||
764 | native_store_gdt(&gdt); | 758 | table_base = gdt->address; |
765 | table_base = gdt.address; | ||
766 | 759 | ||
767 | if (selector & 4) { /* from ldt */ | 760 | if (selector & 4) { /* from ldt */ |
768 | u16 ldt_selector = kvm_read_ldt(); | 761 | u16 ldt_selector = kvm_read_ldt(); |
@@ -883,7 +876,6 @@ static void vmx_load_host_state(struct vcpu_vmx *vmx) | |||
883 | static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 876 | static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
884 | { | 877 | { |
885 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 878 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
886 | u64 tsc_this, delta, new_offset; | ||
887 | u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); | 879 | u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); |
888 | 880 | ||
889 | if (!vmm_exclusive) | 881 | if (!vmm_exclusive) |
@@ -897,37 +889,24 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
897 | } | 889 | } |
898 | 890 | ||
899 | if (vcpu->cpu != cpu) { | 891 | if (vcpu->cpu != cpu) { |
900 | struct desc_ptr dt; | 892 | struct desc_ptr *gdt = &__get_cpu_var(host_gdt); |
901 | unsigned long sysenter_esp; | 893 | unsigned long sysenter_esp; |
902 | 894 | ||
903 | kvm_migrate_timers(vcpu); | ||
904 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); | 895 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); |
905 | local_irq_disable(); | 896 | local_irq_disable(); |
906 | list_add(&vmx->local_vcpus_link, | 897 | list_add(&vmx->local_vcpus_link, |
907 | &per_cpu(vcpus_on_cpu, cpu)); | 898 | &per_cpu(vcpus_on_cpu, cpu)); |
908 | local_irq_enable(); | 899 | local_irq_enable(); |
909 | 900 | ||
910 | vcpu->cpu = cpu; | ||
911 | /* | 901 | /* |
912 | * Linux uses per-cpu TSS and GDT, so set these when switching | 902 | * Linux uses per-cpu TSS and GDT, so set these when switching |
913 | * processors. | 903 | * processors. |
914 | */ | 904 | */ |
915 | vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ | 905 | vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ |
916 | native_store_gdt(&dt); | 906 | vmcs_writel(HOST_GDTR_BASE, gdt->address); /* 22.2.4 */ |
917 | vmcs_writel(HOST_GDTR_BASE, dt.address); /* 22.2.4 */ | ||
918 | 907 | ||
919 | rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); | 908 | rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); |
920 | vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ | 909 | vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ |
921 | |||
922 | /* | ||
923 | * Make sure the time stamp counter is monotonous. | ||
924 | */ | ||
925 | rdtscll(tsc_this); | ||
926 | if (tsc_this < vcpu->arch.host_tsc) { | ||
927 | delta = vcpu->arch.host_tsc - tsc_this; | ||
928 | new_offset = vmcs_read64(TSC_OFFSET) + delta; | ||
929 | vmcs_write64(TSC_OFFSET, new_offset); | ||
930 | } | ||
931 | } | 910 | } |
932 | } | 911 | } |
933 | 912 | ||
@@ -1044,16 +1023,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | |||
1044 | } | 1023 | } |
1045 | 1024 | ||
1046 | if (vmx->rmode.vm86_active) { | 1025 | if (vmx->rmode.vm86_active) { |
1047 | vmx->rmode.irq.pending = true; | 1026 | if (kvm_inject_realmode_interrupt(vcpu, nr) != EMULATE_DONE) |
1048 | vmx->rmode.irq.vector = nr; | 1027 | kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); |
1049 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | ||
1050 | if (kvm_exception_is_soft(nr)) | ||
1051 | vmx->rmode.irq.rip += | ||
1052 | vmx->vcpu.arch.event_exit_inst_len; | ||
1053 | intr_info |= INTR_TYPE_SOFT_INTR; | ||
1054 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); | ||
1055 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); | ||
1056 | kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1); | ||
1057 | return; | 1028 | return; |
1058 | } | 1029 | } |
1059 | 1030 | ||
@@ -1149,12 +1120,17 @@ static u64 guest_read_tsc(void) | |||
1149 | } | 1120 | } |
1150 | 1121 | ||
1151 | /* | 1122 | /* |
1152 | * writes 'guest_tsc' into guest's timestamp counter "register" | 1123 | * writes 'offset' into guest's timestamp counter offset register |
1153 | * guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc | ||
1154 | */ | 1124 | */ |
1155 | static void guest_write_tsc(u64 guest_tsc, u64 host_tsc) | 1125 | static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) |
1126 | { | ||
1127 | vmcs_write64(TSC_OFFSET, offset); | ||
1128 | } | ||
1129 | |||
1130 | static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment) | ||
1156 | { | 1131 | { |
1157 | vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc); | 1132 | u64 offset = vmcs_read64(TSC_OFFSET); |
1133 | vmcs_write64(TSC_OFFSET, offset + adjustment); | ||
1158 | } | 1134 | } |
1159 | 1135 | ||
1160 | /* | 1136 | /* |
@@ -1227,7 +1203,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) | |||
1227 | { | 1203 | { |
1228 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 1204 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
1229 | struct shared_msr_entry *msr; | 1205 | struct shared_msr_entry *msr; |
1230 | u64 host_tsc; | ||
1231 | int ret = 0; | 1206 | int ret = 0; |
1232 | 1207 | ||
1233 | switch (msr_index) { | 1208 | switch (msr_index) { |
@@ -1257,8 +1232,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) | |||
1257 | vmcs_writel(GUEST_SYSENTER_ESP, data); | 1232 | vmcs_writel(GUEST_SYSENTER_ESP, data); |
1258 | break; | 1233 | break; |
1259 | case MSR_IA32_TSC: | 1234 | case MSR_IA32_TSC: |
1260 | rdtscll(host_tsc); | 1235 | kvm_write_tsc(vcpu, data); |
1261 | guest_write_tsc(data, host_tsc); | ||
1262 | break; | 1236 | break; |
1263 | case MSR_IA32_CR_PAT: | 1237 | case MSR_IA32_CR_PAT: |
1264 | if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { | 1238 | if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { |
@@ -1856,20 +1830,20 @@ static void ept_load_pdptrs(struct kvm_vcpu *vcpu) | |||
1856 | return; | 1830 | return; |
1857 | 1831 | ||
1858 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { | 1832 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { |
1859 | vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]); | 1833 | vmcs_write64(GUEST_PDPTR0, vcpu->arch.mmu.pdptrs[0]); |
1860 | vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]); | 1834 | vmcs_write64(GUEST_PDPTR1, vcpu->arch.mmu.pdptrs[1]); |
1861 | vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]); | 1835 | vmcs_write64(GUEST_PDPTR2, vcpu->arch.mmu.pdptrs[2]); |
1862 | vmcs_write64(GUEST_PDPTR3, vcpu->arch.pdptrs[3]); | 1836 | vmcs_write64(GUEST_PDPTR3, vcpu->arch.mmu.pdptrs[3]); |
1863 | } | 1837 | } |
1864 | } | 1838 | } |
1865 | 1839 | ||
1866 | static void ept_save_pdptrs(struct kvm_vcpu *vcpu) | 1840 | static void ept_save_pdptrs(struct kvm_vcpu *vcpu) |
1867 | { | 1841 | { |
1868 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { | 1842 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { |
1869 | vcpu->arch.pdptrs[0] = vmcs_read64(GUEST_PDPTR0); | 1843 | vcpu->arch.mmu.pdptrs[0] = vmcs_read64(GUEST_PDPTR0); |
1870 | vcpu->arch.pdptrs[1] = vmcs_read64(GUEST_PDPTR1); | 1844 | vcpu->arch.mmu.pdptrs[1] = vmcs_read64(GUEST_PDPTR1); |
1871 | vcpu->arch.pdptrs[2] = vmcs_read64(GUEST_PDPTR2); | 1845 | vcpu->arch.mmu.pdptrs[2] = vmcs_read64(GUEST_PDPTR2); |
1872 | vcpu->arch.pdptrs[3] = vmcs_read64(GUEST_PDPTR3); | 1846 | vcpu->arch.mmu.pdptrs[3] = vmcs_read64(GUEST_PDPTR3); |
1873 | } | 1847 | } |
1874 | 1848 | ||
1875 | __set_bit(VCPU_EXREG_PDPTR, | 1849 | __set_bit(VCPU_EXREG_PDPTR, |
@@ -2515,7 +2489,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) | |||
2515 | { | 2489 | { |
2516 | u32 host_sysenter_cs, msr_low, msr_high; | 2490 | u32 host_sysenter_cs, msr_low, msr_high; |
2517 | u32 junk; | 2491 | u32 junk; |
2518 | u64 host_pat, tsc_this, tsc_base; | 2492 | u64 host_pat; |
2519 | unsigned long a; | 2493 | unsigned long a; |
2520 | struct desc_ptr dt; | 2494 | struct desc_ptr dt; |
2521 | int i; | 2495 | int i; |
@@ -2656,12 +2630,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) | |||
2656 | vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE; | 2630 | vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE; |
2657 | vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits); | 2631 | vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits); |
2658 | 2632 | ||
2659 | tsc_base = vmx->vcpu.kvm->arch.vm_init_tsc; | 2633 | kvm_write_tsc(&vmx->vcpu, 0); |
2660 | rdtscll(tsc_this); | ||
2661 | if (tsc_this < vmx->vcpu.kvm->arch.vm_init_tsc) | ||
2662 | tsc_base = tsc_this; | ||
2663 | |||
2664 | guest_write_tsc(0, tsc_base); | ||
2665 | 2634 | ||
2666 | return 0; | 2635 | return 0; |
2667 | } | 2636 | } |
@@ -2834,16 +2803,8 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu) | |||
2834 | 2803 | ||
2835 | ++vcpu->stat.irq_injections; | 2804 | ++vcpu->stat.irq_injections; |
2836 | if (vmx->rmode.vm86_active) { | 2805 | if (vmx->rmode.vm86_active) { |
2837 | vmx->rmode.irq.pending = true; | 2806 | if (kvm_inject_realmode_interrupt(vcpu, irq) != EMULATE_DONE) |
2838 | vmx->rmode.irq.vector = irq; | 2807 | kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); |
2839 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | ||
2840 | if (vcpu->arch.interrupt.soft) | ||
2841 | vmx->rmode.irq.rip += | ||
2842 | vmx->vcpu.arch.event_exit_inst_len; | ||
2843 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | ||
2844 | irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); | ||
2845 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); | ||
2846 | kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1); | ||
2847 | return; | 2808 | return; |
2848 | } | 2809 | } |
2849 | intr = irq | INTR_INFO_VALID_MASK; | 2810 | intr = irq | INTR_INFO_VALID_MASK; |
@@ -2875,14 +2836,8 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu) | |||
2875 | 2836 | ||
2876 | ++vcpu->stat.nmi_injections; | 2837 | ++vcpu->stat.nmi_injections; |
2877 | if (vmx->rmode.vm86_active) { | 2838 | if (vmx->rmode.vm86_active) { |
2878 | vmx->rmode.irq.pending = true; | 2839 | if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR) != EMULATE_DONE) |
2879 | vmx->rmode.irq.vector = NMI_VECTOR; | 2840 | kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); |
2880 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | ||
2881 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | ||
2882 | NMI_VECTOR | INTR_TYPE_SOFT_INTR | | ||
2883 | INTR_INFO_VALID_MASK); | ||
2884 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); | ||
2885 | kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1); | ||
2886 | return; | 2841 | return; |
2887 | } | 2842 | } |
2888 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | 2843 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, |
@@ -3346,6 +3301,7 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu) | |||
3346 | 3301 | ||
3347 | static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu) | 3302 | static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu) |
3348 | { | 3303 | { |
3304 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
3349 | return 1; | 3305 | return 1; |
3350 | } | 3306 | } |
3351 | 3307 | ||
@@ -3358,6 +3314,8 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu) | |||
3358 | cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; | 3314 | cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; |
3359 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); | 3315 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); |
3360 | 3316 | ||
3317 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
3318 | |||
3361 | ++vcpu->stat.irq_window_exits; | 3319 | ++vcpu->stat.irq_window_exits; |
3362 | 3320 | ||
3363 | /* | 3321 | /* |
@@ -3614,6 +3572,7 @@ static int handle_nmi_window(struct kvm_vcpu *vcpu) | |||
3614 | cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING; | 3572 | cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING; |
3615 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); | 3573 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); |
3616 | ++vcpu->stat.nmi_window_exits; | 3574 | ++vcpu->stat.nmi_window_exits; |
3575 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
3617 | 3576 | ||
3618 | return 1; | 3577 | return 1; |
3619 | } | 3578 | } |
@@ -3623,8 +3582,17 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) | |||
3623 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 3582 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
3624 | enum emulation_result err = EMULATE_DONE; | 3583 | enum emulation_result err = EMULATE_DONE; |
3625 | int ret = 1; | 3584 | int ret = 1; |
3585 | u32 cpu_exec_ctrl; | ||
3586 | bool intr_window_requested; | ||
3587 | |||
3588 | cpu_exec_ctrl = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); | ||
3589 | intr_window_requested = cpu_exec_ctrl & CPU_BASED_VIRTUAL_INTR_PENDING; | ||
3626 | 3590 | ||
3627 | while (!guest_state_valid(vcpu)) { | 3591 | while (!guest_state_valid(vcpu)) { |
3592 | if (intr_window_requested | ||
3593 | && (kvm_get_rflags(&vmx->vcpu) & X86_EFLAGS_IF)) | ||
3594 | return handle_interrupt_window(&vmx->vcpu); | ||
3595 | |||
3628 | err = emulate_instruction(vcpu, 0, 0, 0); | 3596 | err = emulate_instruction(vcpu, 0, 0, 0); |
3629 | 3597 | ||
3630 | if (err == EMULATE_DO_MMIO) { | 3598 | if (err == EMULATE_DO_MMIO) { |
@@ -3790,18 +3758,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) | |||
3790 | vmcs_write32(TPR_THRESHOLD, irr); | 3758 | vmcs_write32(TPR_THRESHOLD, irr); |
3791 | } | 3759 | } |
3792 | 3760 | ||
3793 | static void vmx_complete_interrupts(struct vcpu_vmx *vmx) | 3761 | static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx) |
3794 | { | 3762 | { |
3795 | u32 exit_intr_info; | 3763 | u32 exit_intr_info = vmx->exit_intr_info; |
3796 | u32 idt_vectoring_info = vmx->idt_vectoring_info; | ||
3797 | bool unblock_nmi; | ||
3798 | u8 vector; | ||
3799 | int type; | ||
3800 | bool idtv_info_valid; | ||
3801 | |||
3802 | exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); | ||
3803 | |||
3804 | vmx->exit_reason = vmcs_read32(VM_EXIT_REASON); | ||
3805 | 3764 | ||
3806 | /* Handle machine checks before interrupts are enabled */ | 3765 | /* Handle machine checks before interrupts are enabled */ |
3807 | if ((vmx->exit_reason == EXIT_REASON_MCE_DURING_VMENTRY) | 3766 | if ((vmx->exit_reason == EXIT_REASON_MCE_DURING_VMENTRY) |
@@ -3816,8 +3775,16 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) | |||
3816 | asm("int $2"); | 3775 | asm("int $2"); |
3817 | kvm_after_handle_nmi(&vmx->vcpu); | 3776 | kvm_after_handle_nmi(&vmx->vcpu); |
3818 | } | 3777 | } |
3778 | } | ||
3819 | 3779 | ||
3820 | idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; | 3780 | static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) |
3781 | { | ||
3782 | u32 exit_intr_info = vmx->exit_intr_info; | ||
3783 | bool unblock_nmi; | ||
3784 | u8 vector; | ||
3785 | bool idtv_info_valid; | ||
3786 | |||
3787 | idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK; | ||
3821 | 3788 | ||
3822 | if (cpu_has_virtual_nmis()) { | 3789 | if (cpu_has_virtual_nmis()) { |
3823 | unblock_nmi = (exit_intr_info & INTR_INFO_UNBLOCK_NMI) != 0; | 3790 | unblock_nmi = (exit_intr_info & INTR_INFO_UNBLOCK_NMI) != 0; |
@@ -3839,6 +3806,18 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) | |||
3839 | } else if (unlikely(vmx->soft_vnmi_blocked)) | 3806 | } else if (unlikely(vmx->soft_vnmi_blocked)) |
3840 | vmx->vnmi_blocked_time += | 3807 | vmx->vnmi_blocked_time += |
3841 | ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time)); | 3808 | ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time)); |
3809 | } | ||
3810 | |||
3811 | static void __vmx_complete_interrupts(struct vcpu_vmx *vmx, | ||
3812 | u32 idt_vectoring_info, | ||
3813 | int instr_len_field, | ||
3814 | int error_code_field) | ||
3815 | { | ||
3816 | u8 vector; | ||
3817 | int type; | ||
3818 | bool idtv_info_valid; | ||
3819 | |||
3820 | idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; | ||
3842 | 3821 | ||
3843 | vmx->vcpu.arch.nmi_injected = false; | 3822 | vmx->vcpu.arch.nmi_injected = false; |
3844 | kvm_clear_exception_queue(&vmx->vcpu); | 3823 | kvm_clear_exception_queue(&vmx->vcpu); |
@@ -3847,6 +3826,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) | |||
3847 | if (!idtv_info_valid) | 3826 | if (!idtv_info_valid) |
3848 | return; | 3827 | return; |
3849 | 3828 | ||
3829 | kvm_make_request(KVM_REQ_EVENT, &vmx->vcpu); | ||
3830 | |||
3850 | vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK; | 3831 | vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK; |
3851 | type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK; | 3832 | type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK; |
3852 | 3833 | ||
@@ -3863,18 +3844,18 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) | |||
3863 | break; | 3844 | break; |
3864 | case INTR_TYPE_SOFT_EXCEPTION: | 3845 | case INTR_TYPE_SOFT_EXCEPTION: |
3865 | vmx->vcpu.arch.event_exit_inst_len = | 3846 | vmx->vcpu.arch.event_exit_inst_len = |
3866 | vmcs_read32(VM_EXIT_INSTRUCTION_LEN); | 3847 | vmcs_read32(instr_len_field); |
3867 | /* fall through */ | 3848 | /* fall through */ |
3868 | case INTR_TYPE_HARD_EXCEPTION: | 3849 | case INTR_TYPE_HARD_EXCEPTION: |
3869 | if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) { | 3850 | if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) { |
3870 | u32 err = vmcs_read32(IDT_VECTORING_ERROR_CODE); | 3851 | u32 err = vmcs_read32(error_code_field); |
3871 | kvm_queue_exception_e(&vmx->vcpu, vector, err); | 3852 | kvm_queue_exception_e(&vmx->vcpu, vector, err); |
3872 | } else | 3853 | } else |
3873 | kvm_queue_exception(&vmx->vcpu, vector); | 3854 | kvm_queue_exception(&vmx->vcpu, vector); |
3874 | break; | 3855 | break; |
3875 | case INTR_TYPE_SOFT_INTR: | 3856 | case INTR_TYPE_SOFT_INTR: |
3876 | vmx->vcpu.arch.event_exit_inst_len = | 3857 | vmx->vcpu.arch.event_exit_inst_len = |
3877 | vmcs_read32(VM_EXIT_INSTRUCTION_LEN); | 3858 | vmcs_read32(instr_len_field); |
3878 | /* fall through */ | 3859 | /* fall through */ |
3879 | case INTR_TYPE_EXT_INTR: | 3860 | case INTR_TYPE_EXT_INTR: |
3880 | kvm_queue_interrupt(&vmx->vcpu, vector, | 3861 | kvm_queue_interrupt(&vmx->vcpu, vector, |
@@ -3885,27 +3866,21 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) | |||
3885 | } | 3866 | } |
3886 | } | 3867 | } |
3887 | 3868 | ||
3888 | /* | 3869 | static void vmx_complete_interrupts(struct vcpu_vmx *vmx) |
3889 | * Failure to inject an interrupt should give us the information | ||
3890 | * in IDT_VECTORING_INFO_FIELD. However, if the failure occurs | ||
3891 | * when fetching the interrupt redirection bitmap in the real-mode | ||
3892 | * tss, this doesn't happen. So we do it ourselves. | ||
3893 | */ | ||
3894 | static void fixup_rmode_irq(struct vcpu_vmx *vmx) | ||
3895 | { | 3870 | { |
3896 | vmx->rmode.irq.pending = 0; | 3871 | __vmx_complete_interrupts(vmx, vmx->idt_vectoring_info, |
3897 | if (kvm_rip_read(&vmx->vcpu) + 1 != vmx->rmode.irq.rip) | 3872 | VM_EXIT_INSTRUCTION_LEN, |
3898 | return; | 3873 | IDT_VECTORING_ERROR_CODE); |
3899 | kvm_rip_write(&vmx->vcpu, vmx->rmode.irq.rip); | 3874 | } |
3900 | if (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) { | 3875 | |
3901 | vmx->idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK; | 3876 | static void vmx_cancel_injection(struct kvm_vcpu *vcpu) |
3902 | vmx->idt_vectoring_info |= INTR_TYPE_EXT_INTR; | 3877 | { |
3903 | return; | 3878 | __vmx_complete_interrupts(to_vmx(vcpu), |
3904 | } | 3879 | vmcs_read32(VM_ENTRY_INTR_INFO_FIELD), |
3905 | vmx->idt_vectoring_info = | 3880 | VM_ENTRY_INSTRUCTION_LEN, |
3906 | VECTORING_INFO_VALID_MASK | 3881 | VM_ENTRY_EXCEPTION_ERROR_CODE); |
3907 | | INTR_TYPE_EXT_INTR | 3882 | |
3908 | | vmx->rmode.irq.vector; | 3883 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); |
3909 | } | 3884 | } |
3910 | 3885 | ||
3911 | #ifdef CONFIG_X86_64 | 3886 | #ifdef CONFIG_X86_64 |
@@ -4032,7 +4007,7 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
4032 | #endif | 4007 | #endif |
4033 | [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)) | 4008 | [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)) |
4034 | : "cc", "memory" | 4009 | : "cc", "memory" |
4035 | , R"bx", R"di", R"si" | 4010 | , R"ax", R"bx", R"di", R"si" |
4036 | #ifdef CONFIG_X86_64 | 4011 | #ifdef CONFIG_X86_64 |
4037 | , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" | 4012 | , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" |
4038 | #endif | 4013 | #endif |
@@ -4043,12 +4018,15 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
4043 | vcpu->arch.regs_dirty = 0; | 4018 | vcpu->arch.regs_dirty = 0; |
4044 | 4019 | ||
4045 | vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); | 4020 | vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); |
4046 | if (vmx->rmode.irq.pending) | ||
4047 | fixup_rmode_irq(vmx); | ||
4048 | 4021 | ||
4049 | asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); | 4022 | asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); |
4050 | vmx->launched = 1; | 4023 | vmx->launched = 1; |
4051 | 4024 | ||
4025 | vmx->exit_reason = vmcs_read32(VM_EXIT_REASON); | ||
4026 | vmx->exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); | ||
4027 | |||
4028 | vmx_complete_atomic_exit(vmx); | ||
4029 | vmx_recover_nmi_blocking(vmx); | ||
4052 | vmx_complete_interrupts(vmx); | 4030 | vmx_complete_interrupts(vmx); |
4053 | } | 4031 | } |
4054 | 4032 | ||
@@ -4119,6 +4097,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) | |||
4119 | 4097 | ||
4120 | cpu = get_cpu(); | 4098 | cpu = get_cpu(); |
4121 | vmx_vcpu_load(&vmx->vcpu, cpu); | 4099 | vmx_vcpu_load(&vmx->vcpu, cpu); |
4100 | vmx->vcpu.cpu = cpu; | ||
4122 | err = vmx_vcpu_setup(vmx); | 4101 | err = vmx_vcpu_setup(vmx); |
4123 | vmx_vcpu_put(&vmx->vcpu); | 4102 | vmx_vcpu_put(&vmx->vcpu); |
4124 | put_cpu(); | 4103 | put_cpu(); |
@@ -4334,6 +4313,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
4334 | .set_irq = vmx_inject_irq, | 4313 | .set_irq = vmx_inject_irq, |
4335 | .set_nmi = vmx_inject_nmi, | 4314 | .set_nmi = vmx_inject_nmi, |
4336 | .queue_exception = vmx_queue_exception, | 4315 | .queue_exception = vmx_queue_exception, |
4316 | .cancel_injection = vmx_cancel_injection, | ||
4337 | .interrupt_allowed = vmx_interrupt_allowed, | 4317 | .interrupt_allowed = vmx_interrupt_allowed, |
4338 | .nmi_allowed = vmx_nmi_allowed, | 4318 | .nmi_allowed = vmx_nmi_allowed, |
4339 | .get_nmi_mask = vmx_get_nmi_mask, | 4319 | .get_nmi_mask = vmx_get_nmi_mask, |
@@ -4356,6 +4336,11 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
4356 | .set_supported_cpuid = vmx_set_supported_cpuid, | 4336 | .set_supported_cpuid = vmx_set_supported_cpuid, |
4357 | 4337 | ||
4358 | .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit, | 4338 | .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit, |
4339 | |||
4340 | .write_tsc_offset = vmx_write_tsc_offset, | ||
4341 | .adjust_tsc_offset = vmx_adjust_tsc_offset, | ||
4342 | |||
4343 | .set_tdp_cr3 = vmx_set_cr3, | ||
4359 | }; | 4344 | }; |
4360 | 4345 | ||
4361 | static int __init vmx_init(void) | 4346 | static int __init vmx_init(void) |