diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-10-30 04:43:08 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-10-30 04:43:08 -0400 |
commit | 169ed55bd30305b933f52bfab32a58671d44ab68 (patch) | |
tree | 32e280957474f458901abfce16fa2a1687ef7497 /arch/x86/kvm/svm.c | |
parent | 3d7851b3cdd43a734e5cc4c643fd886ab28ad4d5 (diff) | |
parent | 45f81b1c96d9793e47ce925d257ea693ce0b193e (diff) |
Merge branch 'tip/perf/jump-label-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into perf/urgent
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 283 |
1 files changed, 221 insertions, 62 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 8a3f9f64f86f..82e144a4e514 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * AMD SVM support | 4 | * AMD SVM support |
5 | * | 5 | * |
6 | * Copyright (C) 2006 Qumranet, Inc. | 6 | * Copyright (C) 2006 Qumranet, Inc. |
7 | * Copyright 2010 Red Hat, Inc. and/or its affilates. | 7 | * Copyright 2010 Red Hat, Inc. and/or its affiliates. |
8 | * | 8 | * |
9 | * Authors: | 9 | * Authors: |
10 | * Yaniv Kamay <yaniv@qumranet.com> | 10 | * Yaniv Kamay <yaniv@qumranet.com> |
@@ -88,6 +88,14 @@ struct nested_state { | |||
88 | /* A VMEXIT is required but not yet emulated */ | 88 | /* A VMEXIT is required but not yet emulated */ |
89 | bool exit_required; | 89 | bool exit_required; |
90 | 90 | ||
91 | /* | ||
92 | * If we vmexit during an instruction emulation we need this to restore | ||
93 | * the l1 guest rip after the emulation | ||
94 | */ | ||
95 | unsigned long vmexit_rip; | ||
96 | unsigned long vmexit_rsp; | ||
97 | unsigned long vmexit_rax; | ||
98 | |||
91 | /* cache for intercepts of the guest */ | 99 | /* cache for intercepts of the guest */ |
92 | u16 intercept_cr_read; | 100 | u16 intercept_cr_read; |
93 | u16 intercept_cr_write; | 101 | u16 intercept_cr_write; |
@@ -96,6 +104,8 @@ struct nested_state { | |||
96 | u32 intercept_exceptions; | 104 | u32 intercept_exceptions; |
97 | u64 intercept; | 105 | u64 intercept; |
98 | 106 | ||
107 | /* Nested Paging related state */ | ||
108 | u64 nested_cr3; | ||
99 | }; | 109 | }; |
100 | 110 | ||
101 | #define MSRPM_OFFSETS 16 | 111 | #define MSRPM_OFFSETS 16 |
@@ -284,6 +294,15 @@ static inline void flush_guest_tlb(struct kvm_vcpu *vcpu) | |||
284 | force_new_asid(vcpu); | 294 | force_new_asid(vcpu); |
285 | } | 295 | } |
286 | 296 | ||
297 | static int get_npt_level(void) | ||
298 | { | ||
299 | #ifdef CONFIG_X86_64 | ||
300 | return PT64_ROOT_LEVEL; | ||
301 | #else | ||
302 | return PT32E_ROOT_LEVEL; | ||
303 | #endif | ||
304 | } | ||
305 | |||
287 | static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) | 306 | static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) |
288 | { | 307 | { |
289 | vcpu->arch.efer = efer; | 308 | vcpu->arch.efer = efer; |
@@ -701,6 +720,29 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type) | |||
701 | seg->base = 0; | 720 | seg->base = 0; |
702 | } | 721 | } |
703 | 722 | ||
723 | static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) | ||
724 | { | ||
725 | struct vcpu_svm *svm = to_svm(vcpu); | ||
726 | u64 g_tsc_offset = 0; | ||
727 | |||
728 | if (is_nested(svm)) { | ||
729 | g_tsc_offset = svm->vmcb->control.tsc_offset - | ||
730 | svm->nested.hsave->control.tsc_offset; | ||
731 | svm->nested.hsave->control.tsc_offset = offset; | ||
732 | } | ||
733 | |||
734 | svm->vmcb->control.tsc_offset = offset + g_tsc_offset; | ||
735 | } | ||
736 | |||
737 | static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment) | ||
738 | { | ||
739 | struct vcpu_svm *svm = to_svm(vcpu); | ||
740 | |||
741 | svm->vmcb->control.tsc_offset += adjustment; | ||
742 | if (is_nested(svm)) | ||
743 | svm->nested.hsave->control.tsc_offset += adjustment; | ||
744 | } | ||
745 | |||
704 | static void init_vmcb(struct vcpu_svm *svm) | 746 | static void init_vmcb(struct vcpu_svm *svm) |
705 | { | 747 | { |
706 | struct vmcb_control_area *control = &svm->vmcb->control; | 748 | struct vmcb_control_area *control = &svm->vmcb->control; |
@@ -793,7 +835,7 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
793 | init_sys_seg(&save->ldtr, SEG_TYPE_LDT); | 835 | init_sys_seg(&save->ldtr, SEG_TYPE_LDT); |
794 | init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16); | 836 | init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16); |
795 | 837 | ||
796 | save->efer = EFER_SVME; | 838 | svm_set_efer(&svm->vcpu, 0); |
797 | save->dr6 = 0xffff0ff0; | 839 | save->dr6 = 0xffff0ff0; |
798 | save->dr7 = 0x400; | 840 | save->dr7 = 0x400; |
799 | save->rflags = 2; | 841 | save->rflags = 2; |
@@ -804,8 +846,8 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
804 | * This is the guest-visible cr0 value. | 846 | * This is the guest-visible cr0 value. |
805 | * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. | 847 | * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. |
806 | */ | 848 | */ |
807 | svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; | 849 | svm->vcpu.arch.cr0 = 0; |
808 | (void)kvm_set_cr0(&svm->vcpu, svm->vcpu.arch.cr0); | 850 | (void)kvm_set_cr0(&svm->vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); |
809 | 851 | ||
810 | save->cr4 = X86_CR4_PAE; | 852 | save->cr4 = X86_CR4_PAE; |
811 | /* rdx = ?? */ | 853 | /* rdx = ?? */ |
@@ -901,7 +943,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
901 | svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; | 943 | svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; |
902 | svm->asid_generation = 0; | 944 | svm->asid_generation = 0; |
903 | init_vmcb(svm); | 945 | init_vmcb(svm); |
904 | svm->vmcb->control.tsc_offset = 0-native_read_tsc(); | 946 | kvm_write_tsc(&svm->vcpu, 0); |
905 | 947 | ||
906 | err = fx_init(&svm->vcpu); | 948 | err = fx_init(&svm->vcpu); |
907 | if (err) | 949 | if (err) |
@@ -947,20 +989,6 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
947 | int i; | 989 | int i; |
948 | 990 | ||
949 | if (unlikely(cpu != vcpu->cpu)) { | 991 | if (unlikely(cpu != vcpu->cpu)) { |
950 | u64 delta; | ||
951 | |||
952 | if (check_tsc_unstable()) { | ||
953 | /* | ||
954 | * Make sure that the guest sees a monotonically | ||
955 | * increasing TSC. | ||
956 | */ | ||
957 | delta = vcpu->arch.host_tsc - native_read_tsc(); | ||
958 | svm->vmcb->control.tsc_offset += delta; | ||
959 | if (is_nested(svm)) | ||
960 | svm->nested.hsave->control.tsc_offset += delta; | ||
961 | } | ||
962 | vcpu->cpu = cpu; | ||
963 | kvm_migrate_timers(vcpu); | ||
964 | svm->asid_generation = 0; | 992 | svm->asid_generation = 0; |
965 | } | 993 | } |
966 | 994 | ||
@@ -976,8 +1004,6 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) | |||
976 | ++vcpu->stat.host_state_reload; | 1004 | ++vcpu->stat.host_state_reload; |
977 | for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) | 1005 | for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) |
978 | wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); | 1006 | wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); |
979 | |||
980 | vcpu->arch.host_tsc = native_read_tsc(); | ||
981 | } | 1007 | } |
982 | 1008 | ||
983 | static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) | 1009 | static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) |
@@ -995,7 +1021,7 @@ static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) | |||
995 | switch (reg) { | 1021 | switch (reg) { |
996 | case VCPU_EXREG_PDPTR: | 1022 | case VCPU_EXREG_PDPTR: |
997 | BUG_ON(!npt_enabled); | 1023 | BUG_ON(!npt_enabled); |
998 | load_pdptrs(vcpu, vcpu->arch.cr3); | 1024 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); |
999 | break; | 1025 | break; |
1000 | default: | 1026 | default: |
1001 | BUG(); | 1027 | BUG(); |
@@ -1206,8 +1232,12 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
1206 | if (old == new) { | 1232 | if (old == new) { |
1207 | /* cr0 write with ts and mp unchanged */ | 1233 | /* cr0 write with ts and mp unchanged */ |
1208 | svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE; | 1234 | svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE; |
1209 | if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE) | 1235 | if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE) { |
1236 | svm->nested.vmexit_rip = kvm_rip_read(vcpu); | ||
1237 | svm->nested.vmexit_rsp = kvm_register_read(vcpu, VCPU_REGS_RSP); | ||
1238 | svm->nested.vmexit_rax = kvm_register_read(vcpu, VCPU_REGS_RAX); | ||
1210 | return; | 1239 | return; |
1240 | } | ||
1211 | } | 1241 | } |
1212 | } | 1242 | } |
1213 | 1243 | ||
@@ -1581,6 +1611,54 @@ static int vmmcall_interception(struct vcpu_svm *svm) | |||
1581 | return 1; | 1611 | return 1; |
1582 | } | 1612 | } |
1583 | 1613 | ||
1614 | static unsigned long nested_svm_get_tdp_cr3(struct kvm_vcpu *vcpu) | ||
1615 | { | ||
1616 | struct vcpu_svm *svm = to_svm(vcpu); | ||
1617 | |||
1618 | return svm->nested.nested_cr3; | ||
1619 | } | ||
1620 | |||
1621 | static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu, | ||
1622 | unsigned long root) | ||
1623 | { | ||
1624 | struct vcpu_svm *svm = to_svm(vcpu); | ||
1625 | |||
1626 | svm->vmcb->control.nested_cr3 = root; | ||
1627 | force_new_asid(vcpu); | ||
1628 | } | ||
1629 | |||
1630 | static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu) | ||
1631 | { | ||
1632 | struct vcpu_svm *svm = to_svm(vcpu); | ||
1633 | |||
1634 | svm->vmcb->control.exit_code = SVM_EXIT_NPF; | ||
1635 | svm->vmcb->control.exit_code_hi = 0; | ||
1636 | svm->vmcb->control.exit_info_1 = vcpu->arch.fault.error_code; | ||
1637 | svm->vmcb->control.exit_info_2 = vcpu->arch.fault.address; | ||
1638 | |||
1639 | nested_svm_vmexit(svm); | ||
1640 | } | ||
1641 | |||
1642 | static int nested_svm_init_mmu_context(struct kvm_vcpu *vcpu) | ||
1643 | { | ||
1644 | int r; | ||
1645 | |||
1646 | r = kvm_init_shadow_mmu(vcpu, &vcpu->arch.mmu); | ||
1647 | |||
1648 | vcpu->arch.mmu.set_cr3 = nested_svm_set_tdp_cr3; | ||
1649 | vcpu->arch.mmu.get_cr3 = nested_svm_get_tdp_cr3; | ||
1650 | vcpu->arch.mmu.inject_page_fault = nested_svm_inject_npf_exit; | ||
1651 | vcpu->arch.mmu.shadow_root_level = get_npt_level(); | ||
1652 | vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu; | ||
1653 | |||
1654 | return r; | ||
1655 | } | ||
1656 | |||
1657 | static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu) | ||
1658 | { | ||
1659 | vcpu->arch.walk_mmu = &vcpu->arch.mmu; | ||
1660 | } | ||
1661 | |||
1584 | static int nested_svm_check_permissions(struct vcpu_svm *svm) | 1662 | static int nested_svm_check_permissions(struct vcpu_svm *svm) |
1585 | { | 1663 | { |
1586 | if (!(svm->vcpu.arch.efer & EFER_SVME) | 1664 | if (!(svm->vcpu.arch.efer & EFER_SVME) |
@@ -1629,6 +1707,14 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm) | |||
1629 | if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) | 1707 | if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) |
1630 | return false; | 1708 | return false; |
1631 | 1709 | ||
1710 | /* | ||
1711 | * if vmexit was already requested (by intercepted exception | ||
1712 | * for instance) do not overwrite it with "external interrupt" | ||
1713 | * vmexit. | ||
1714 | */ | ||
1715 | if (svm->nested.exit_required) | ||
1716 | return false; | ||
1717 | |||
1632 | svm->vmcb->control.exit_code = SVM_EXIT_INTR; | 1718 | svm->vmcb->control.exit_code = SVM_EXIT_INTR; |
1633 | svm->vmcb->control.exit_info_1 = 0; | 1719 | svm->vmcb->control.exit_info_1 = 0; |
1634 | svm->vmcb->control.exit_info_2 = 0; | 1720 | svm->vmcb->control.exit_info_2 = 0; |
@@ -1896,6 +1982,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1896 | nested_vmcb->save.ds = vmcb->save.ds; | 1982 | nested_vmcb->save.ds = vmcb->save.ds; |
1897 | nested_vmcb->save.gdtr = vmcb->save.gdtr; | 1983 | nested_vmcb->save.gdtr = vmcb->save.gdtr; |
1898 | nested_vmcb->save.idtr = vmcb->save.idtr; | 1984 | nested_vmcb->save.idtr = vmcb->save.idtr; |
1985 | nested_vmcb->save.efer = svm->vcpu.arch.efer; | ||
1899 | nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu); | 1986 | nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu); |
1900 | nested_vmcb->save.cr3 = svm->vcpu.arch.cr3; | 1987 | nested_vmcb->save.cr3 = svm->vcpu.arch.cr3; |
1901 | nested_vmcb->save.cr2 = vmcb->save.cr2; | 1988 | nested_vmcb->save.cr2 = vmcb->save.cr2; |
@@ -1917,6 +2004,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1917 | nested_vmcb->control.exit_info_2 = vmcb->control.exit_info_2; | 2004 | nested_vmcb->control.exit_info_2 = vmcb->control.exit_info_2; |
1918 | nested_vmcb->control.exit_int_info = vmcb->control.exit_int_info; | 2005 | nested_vmcb->control.exit_int_info = vmcb->control.exit_int_info; |
1919 | nested_vmcb->control.exit_int_info_err = vmcb->control.exit_int_info_err; | 2006 | nested_vmcb->control.exit_int_info_err = vmcb->control.exit_int_info_err; |
2007 | nested_vmcb->control.next_rip = vmcb->control.next_rip; | ||
1920 | 2008 | ||
1921 | /* | 2009 | /* |
1922 | * If we emulate a VMRUN/#VMEXIT in the same host #vmexit cycle we have | 2010 | * If we emulate a VMRUN/#VMEXIT in the same host #vmexit cycle we have |
@@ -1947,6 +2035,8 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1947 | kvm_clear_exception_queue(&svm->vcpu); | 2035 | kvm_clear_exception_queue(&svm->vcpu); |
1948 | kvm_clear_interrupt_queue(&svm->vcpu); | 2036 | kvm_clear_interrupt_queue(&svm->vcpu); |
1949 | 2037 | ||
2038 | svm->nested.nested_cr3 = 0; | ||
2039 | |||
1950 | /* Restore selected save entries */ | 2040 | /* Restore selected save entries */ |
1951 | svm->vmcb->save.es = hsave->save.es; | 2041 | svm->vmcb->save.es = hsave->save.es; |
1952 | svm->vmcb->save.cs = hsave->save.cs; | 2042 | svm->vmcb->save.cs = hsave->save.cs; |
@@ -1973,6 +2063,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1973 | 2063 | ||
1974 | nested_svm_unmap(page); | 2064 | nested_svm_unmap(page); |
1975 | 2065 | ||
2066 | nested_svm_uninit_mmu_context(&svm->vcpu); | ||
1976 | kvm_mmu_reset_context(&svm->vcpu); | 2067 | kvm_mmu_reset_context(&svm->vcpu); |
1977 | kvm_mmu_load(&svm->vcpu); | 2068 | kvm_mmu_load(&svm->vcpu); |
1978 | 2069 | ||
@@ -2012,6 +2103,20 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) | |||
2012 | return true; | 2103 | return true; |
2013 | } | 2104 | } |
2014 | 2105 | ||
2106 | static bool nested_vmcb_checks(struct vmcb *vmcb) | ||
2107 | { | ||
2108 | if ((vmcb->control.intercept & (1ULL << INTERCEPT_VMRUN)) == 0) | ||
2109 | return false; | ||
2110 | |||
2111 | if (vmcb->control.asid == 0) | ||
2112 | return false; | ||
2113 | |||
2114 | if (vmcb->control.nested_ctl && !npt_enabled) | ||
2115 | return false; | ||
2116 | |||
2117 | return true; | ||
2118 | } | ||
2119 | |||
2015 | static bool nested_svm_vmrun(struct vcpu_svm *svm) | 2120 | static bool nested_svm_vmrun(struct vcpu_svm *svm) |
2016 | { | 2121 | { |
2017 | struct vmcb *nested_vmcb; | 2122 | struct vmcb *nested_vmcb; |
@@ -2026,7 +2131,18 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2026 | if (!nested_vmcb) | 2131 | if (!nested_vmcb) |
2027 | return false; | 2132 | return false; |
2028 | 2133 | ||
2029 | trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, vmcb_gpa, | 2134 | if (!nested_vmcb_checks(nested_vmcb)) { |
2135 | nested_vmcb->control.exit_code = SVM_EXIT_ERR; | ||
2136 | nested_vmcb->control.exit_code_hi = 0; | ||
2137 | nested_vmcb->control.exit_info_1 = 0; | ||
2138 | nested_vmcb->control.exit_info_2 = 0; | ||
2139 | |||
2140 | nested_svm_unmap(page); | ||
2141 | |||
2142 | return false; | ||
2143 | } | ||
2144 | |||
2145 | trace_kvm_nested_vmrun(svm->vmcb->save.rip, vmcb_gpa, | ||
2030 | nested_vmcb->save.rip, | 2146 | nested_vmcb->save.rip, |
2031 | nested_vmcb->control.int_ctl, | 2147 | nested_vmcb->control.int_ctl, |
2032 | nested_vmcb->control.event_inj, | 2148 | nested_vmcb->control.event_inj, |
@@ -2055,7 +2171,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2055 | hsave->save.cr0 = kvm_read_cr0(&svm->vcpu); | 2171 | hsave->save.cr0 = kvm_read_cr0(&svm->vcpu); |
2056 | hsave->save.cr4 = svm->vcpu.arch.cr4; | 2172 | hsave->save.cr4 = svm->vcpu.arch.cr4; |
2057 | hsave->save.rflags = vmcb->save.rflags; | 2173 | hsave->save.rflags = vmcb->save.rflags; |
2058 | hsave->save.rip = svm->next_rip; | 2174 | hsave->save.rip = kvm_rip_read(&svm->vcpu); |
2059 | hsave->save.rsp = vmcb->save.rsp; | 2175 | hsave->save.rsp = vmcb->save.rsp; |
2060 | hsave->save.rax = vmcb->save.rax; | 2176 | hsave->save.rax = vmcb->save.rax; |
2061 | if (npt_enabled) | 2177 | if (npt_enabled) |
@@ -2070,6 +2186,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2070 | else | 2186 | else |
2071 | svm->vcpu.arch.hflags &= ~HF_HIF_MASK; | 2187 | svm->vcpu.arch.hflags &= ~HF_HIF_MASK; |
2072 | 2188 | ||
2189 | if (nested_vmcb->control.nested_ctl) { | ||
2190 | kvm_mmu_unload(&svm->vcpu); | ||
2191 | svm->nested.nested_cr3 = nested_vmcb->control.nested_cr3; | ||
2192 | nested_svm_init_mmu_context(&svm->vcpu); | ||
2193 | } | ||
2194 | |||
2073 | /* Load the nested guest state */ | 2195 | /* Load the nested guest state */ |
2074 | svm->vmcb->save.es = nested_vmcb->save.es; | 2196 | svm->vmcb->save.es = nested_vmcb->save.es; |
2075 | svm->vmcb->save.cs = nested_vmcb->save.cs; | 2197 | svm->vmcb->save.cs = nested_vmcb->save.cs; |
@@ -2227,8 +2349,8 @@ static int vmrun_interception(struct vcpu_svm *svm) | |||
2227 | if (nested_svm_check_permissions(svm)) | 2349 | if (nested_svm_check_permissions(svm)) |
2228 | return 1; | 2350 | return 1; |
2229 | 2351 | ||
2230 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 2352 | /* Save rip after vmrun instruction */ |
2231 | skip_emulated_instruction(&svm->vcpu); | 2353 | kvm_rip_write(&svm->vcpu, kvm_rip_read(&svm->vcpu) + 3); |
2232 | 2354 | ||
2233 | if (!nested_svm_vmrun(svm)) | 2355 | if (!nested_svm_vmrun(svm)) |
2234 | return 1; | 2356 | return 1; |
@@ -2257,6 +2379,7 @@ static int stgi_interception(struct vcpu_svm *svm) | |||
2257 | 2379 | ||
2258 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 2380 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
2259 | skip_emulated_instruction(&svm->vcpu); | 2381 | skip_emulated_instruction(&svm->vcpu); |
2382 | kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); | ||
2260 | 2383 | ||
2261 | enable_gif(svm); | 2384 | enable_gif(svm); |
2262 | 2385 | ||
@@ -2399,6 +2522,23 @@ static int emulate_on_interception(struct vcpu_svm *svm) | |||
2399 | return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; | 2522 | return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; |
2400 | } | 2523 | } |
2401 | 2524 | ||
2525 | static int cr0_write_interception(struct vcpu_svm *svm) | ||
2526 | { | ||
2527 | struct kvm_vcpu *vcpu = &svm->vcpu; | ||
2528 | int r; | ||
2529 | |||
2530 | r = emulate_instruction(&svm->vcpu, 0, 0, 0); | ||
2531 | |||
2532 | if (svm->nested.vmexit_rip) { | ||
2533 | kvm_register_write(vcpu, VCPU_REGS_RIP, svm->nested.vmexit_rip); | ||
2534 | kvm_register_write(vcpu, VCPU_REGS_RSP, svm->nested.vmexit_rsp); | ||
2535 | kvm_register_write(vcpu, VCPU_REGS_RAX, svm->nested.vmexit_rax); | ||
2536 | svm->nested.vmexit_rip = 0; | ||
2537 | } | ||
2538 | |||
2539 | return r == EMULATE_DONE; | ||
2540 | } | ||
2541 | |||
2402 | static int cr8_write_interception(struct vcpu_svm *svm) | 2542 | static int cr8_write_interception(struct vcpu_svm *svm) |
2403 | { | 2543 | { |
2404 | struct kvm_run *kvm_run = svm->vcpu.run; | 2544 | struct kvm_run *kvm_run = svm->vcpu.run; |
@@ -2542,20 +2682,9 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
2542 | struct vcpu_svm *svm = to_svm(vcpu); | 2682 | struct vcpu_svm *svm = to_svm(vcpu); |
2543 | 2683 | ||
2544 | switch (ecx) { | 2684 | switch (ecx) { |
2545 | case MSR_IA32_TSC: { | 2685 | case MSR_IA32_TSC: |
2546 | u64 tsc_offset = data - native_read_tsc(); | 2686 | kvm_write_tsc(vcpu, data); |
2547 | u64 g_tsc_offset = 0; | ||
2548 | |||
2549 | if (is_nested(svm)) { | ||
2550 | g_tsc_offset = svm->vmcb->control.tsc_offset - | ||
2551 | svm->nested.hsave->control.tsc_offset; | ||
2552 | svm->nested.hsave->control.tsc_offset = tsc_offset; | ||
2553 | } | ||
2554 | |||
2555 | svm->vmcb->control.tsc_offset = tsc_offset + g_tsc_offset; | ||
2556 | |||
2557 | break; | 2687 | break; |
2558 | } | ||
2559 | case MSR_STAR: | 2688 | case MSR_STAR: |
2560 | svm->vmcb->save.star = data; | 2689 | svm->vmcb->save.star = data; |
2561 | break; | 2690 | break; |
@@ -2643,6 +2772,7 @@ static int interrupt_window_interception(struct vcpu_svm *svm) | |||
2643 | { | 2772 | { |
2644 | struct kvm_run *kvm_run = svm->vcpu.run; | 2773 | struct kvm_run *kvm_run = svm->vcpu.run; |
2645 | 2774 | ||
2775 | kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); | ||
2646 | svm_clear_vintr(svm); | 2776 | svm_clear_vintr(svm); |
2647 | svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; | 2777 | svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; |
2648 | /* | 2778 | /* |
@@ -2672,7 +2802,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
2672 | [SVM_EXIT_READ_CR4] = emulate_on_interception, | 2802 | [SVM_EXIT_READ_CR4] = emulate_on_interception, |
2673 | [SVM_EXIT_READ_CR8] = emulate_on_interception, | 2803 | [SVM_EXIT_READ_CR8] = emulate_on_interception, |
2674 | [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, | 2804 | [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, |
2675 | [SVM_EXIT_WRITE_CR0] = emulate_on_interception, | 2805 | [SVM_EXIT_WRITE_CR0] = cr0_write_interception, |
2676 | [SVM_EXIT_WRITE_CR3] = emulate_on_interception, | 2806 | [SVM_EXIT_WRITE_CR3] = emulate_on_interception, |
2677 | [SVM_EXIT_WRITE_CR4] = emulate_on_interception, | 2807 | [SVM_EXIT_WRITE_CR4] = emulate_on_interception, |
2678 | [SVM_EXIT_WRITE_CR8] = cr8_write_interception, | 2808 | [SVM_EXIT_WRITE_CR8] = cr8_write_interception, |
@@ -2871,7 +3001,8 @@ static int handle_exit(struct kvm_vcpu *vcpu) | |||
2871 | 3001 | ||
2872 | if (is_external_interrupt(svm->vmcb->control.exit_int_info) && | 3002 | if (is_external_interrupt(svm->vmcb->control.exit_int_info) && |
2873 | exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR && | 3003 | exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR && |
2874 | exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH) | 3004 | exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH && |
3005 | exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI) | ||
2875 | printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x " | 3006 | printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x " |
2876 | "exit_code 0x%x\n", | 3007 | "exit_code 0x%x\n", |
2877 | __func__, svm->vmcb->control.exit_int_info, | 3008 | __func__, svm->vmcb->control.exit_int_info, |
@@ -3088,8 +3219,10 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) | |||
3088 | 3219 | ||
3089 | svm->int3_injected = 0; | 3220 | svm->int3_injected = 0; |
3090 | 3221 | ||
3091 | if (svm->vcpu.arch.hflags & HF_IRET_MASK) | 3222 | if (svm->vcpu.arch.hflags & HF_IRET_MASK) { |
3092 | svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK); | 3223 | svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK); |
3224 | kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); | ||
3225 | } | ||
3093 | 3226 | ||
3094 | svm->vcpu.arch.nmi_injected = false; | 3227 | svm->vcpu.arch.nmi_injected = false; |
3095 | kvm_clear_exception_queue(&svm->vcpu); | 3228 | kvm_clear_exception_queue(&svm->vcpu); |
@@ -3098,6 +3231,8 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) | |||
3098 | if (!(exitintinfo & SVM_EXITINTINFO_VALID)) | 3231 | if (!(exitintinfo & SVM_EXITINTINFO_VALID)) |
3099 | return; | 3232 | return; |
3100 | 3233 | ||
3234 | kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); | ||
3235 | |||
3101 | vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK; | 3236 | vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK; |
3102 | type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK; | 3237 | type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK; |
3103 | 3238 | ||
@@ -3134,6 +3269,17 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) | |||
3134 | } | 3269 | } |
3135 | } | 3270 | } |
3136 | 3271 | ||
3272 | static void svm_cancel_injection(struct kvm_vcpu *vcpu) | ||
3273 | { | ||
3274 | struct vcpu_svm *svm = to_svm(vcpu); | ||
3275 | struct vmcb_control_area *control = &svm->vmcb->control; | ||
3276 | |||
3277 | control->exit_int_info = control->event_inj; | ||
3278 | control->exit_int_info_err = control->event_inj_err; | ||
3279 | control->event_inj = 0; | ||
3280 | svm_complete_interrupts(svm); | ||
3281 | } | ||
3282 | |||
3137 | #ifdef CONFIG_X86_64 | 3283 | #ifdef CONFIG_X86_64 |
3138 | #define R "r" | 3284 | #define R "r" |
3139 | #else | 3285 | #else |
@@ -3167,9 +3313,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
3167 | savesegment(gs, gs_selector); | 3313 | savesegment(gs, gs_selector); |
3168 | ldt_selector = kvm_read_ldt(); | 3314 | ldt_selector = kvm_read_ldt(); |
3169 | svm->vmcb->save.cr2 = vcpu->arch.cr2; | 3315 | svm->vmcb->save.cr2 = vcpu->arch.cr2; |
3170 | /* required for live migration with NPT */ | ||
3171 | if (npt_enabled) | ||
3172 | svm->vmcb->save.cr3 = vcpu->arch.cr3; | ||
3173 | 3316 | ||
3174 | clgi(); | 3317 | clgi(); |
3175 | 3318 | ||
@@ -3291,16 +3434,22 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root) | |||
3291 | { | 3434 | { |
3292 | struct vcpu_svm *svm = to_svm(vcpu); | 3435 | struct vcpu_svm *svm = to_svm(vcpu); |
3293 | 3436 | ||
3294 | if (npt_enabled) { | ||
3295 | svm->vmcb->control.nested_cr3 = root; | ||
3296 | force_new_asid(vcpu); | ||
3297 | return; | ||
3298 | } | ||
3299 | |||
3300 | svm->vmcb->save.cr3 = root; | 3437 | svm->vmcb->save.cr3 = root; |
3301 | force_new_asid(vcpu); | 3438 | force_new_asid(vcpu); |
3302 | } | 3439 | } |
3303 | 3440 | ||
3441 | static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root) | ||
3442 | { | ||
3443 | struct vcpu_svm *svm = to_svm(vcpu); | ||
3444 | |||
3445 | svm->vmcb->control.nested_cr3 = root; | ||
3446 | |||
3447 | /* Also sync guest cr3 here in case we live migrate */ | ||
3448 | svm->vmcb->save.cr3 = vcpu->arch.cr3; | ||
3449 | |||
3450 | force_new_asid(vcpu); | ||
3451 | } | ||
3452 | |||
3304 | static int is_disabled(void) | 3453 | static int is_disabled(void) |
3305 | { | 3454 | { |
3306 | u64 vm_cr; | 3455 | u64 vm_cr; |
@@ -3333,15 +3482,6 @@ static bool svm_cpu_has_accelerated_tpr(void) | |||
3333 | return false; | 3482 | return false; |
3334 | } | 3483 | } |
3335 | 3484 | ||
3336 | static int get_npt_level(void) | ||
3337 | { | ||
3338 | #ifdef CONFIG_X86_64 | ||
3339 | return PT64_ROOT_LEVEL; | ||
3340 | #else | ||
3341 | return PT32E_ROOT_LEVEL; | ||
3342 | #endif | ||
3343 | } | ||
3344 | |||
3345 | static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio) | 3485 | static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio) |
3346 | { | 3486 | { |
3347 | return 0; | 3487 | return 0; |
@@ -3354,12 +3494,25 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) | |||
3354 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) | 3494 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) |
3355 | { | 3495 | { |
3356 | switch (func) { | 3496 | switch (func) { |
3497 | case 0x80000001: | ||
3498 | if (nested) | ||
3499 | entry->ecx |= (1 << 2); /* Set SVM bit */ | ||
3500 | break; | ||
3357 | case 0x8000000A: | 3501 | case 0x8000000A: |
3358 | entry->eax = 1; /* SVM revision 1 */ | 3502 | entry->eax = 1; /* SVM revision 1 */ |
3359 | entry->ebx = 8; /* Lets support 8 ASIDs in case we add proper | 3503 | entry->ebx = 8; /* Lets support 8 ASIDs in case we add proper |
3360 | ASID emulation to nested SVM */ | 3504 | ASID emulation to nested SVM */ |
3361 | entry->ecx = 0; /* Reserved */ | 3505 | entry->ecx = 0; /* Reserved */ |
3362 | entry->edx = 0; /* Do not support any additional features */ | 3506 | entry->edx = 0; /* Per default do not support any |
3507 | additional features */ | ||
3508 | |||
3509 | /* Support next_rip if host supports it */ | ||
3510 | if (svm_has(SVM_FEATURE_NRIP)) | ||
3511 | entry->edx |= SVM_FEATURE_NRIP; | ||
3512 | |||
3513 | /* Support NPT for the guest if enabled */ | ||
3514 | if (npt_enabled) | ||
3515 | entry->edx |= SVM_FEATURE_NPT; | ||
3363 | 3516 | ||
3364 | break; | 3517 | break; |
3365 | } | 3518 | } |
@@ -3497,6 +3650,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
3497 | .set_irq = svm_set_irq, | 3650 | .set_irq = svm_set_irq, |
3498 | .set_nmi = svm_inject_nmi, | 3651 | .set_nmi = svm_inject_nmi, |
3499 | .queue_exception = svm_queue_exception, | 3652 | .queue_exception = svm_queue_exception, |
3653 | .cancel_injection = svm_cancel_injection, | ||
3500 | .interrupt_allowed = svm_interrupt_allowed, | 3654 | .interrupt_allowed = svm_interrupt_allowed, |
3501 | .nmi_allowed = svm_nmi_allowed, | 3655 | .nmi_allowed = svm_nmi_allowed, |
3502 | .get_nmi_mask = svm_get_nmi_mask, | 3656 | .get_nmi_mask = svm_get_nmi_mask, |
@@ -3519,6 +3673,11 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
3519 | .set_supported_cpuid = svm_set_supported_cpuid, | 3673 | .set_supported_cpuid = svm_set_supported_cpuid, |
3520 | 3674 | ||
3521 | .has_wbinvd_exit = svm_has_wbinvd_exit, | 3675 | .has_wbinvd_exit = svm_has_wbinvd_exit, |
3676 | |||
3677 | .write_tsc_offset = svm_write_tsc_offset, | ||
3678 | .adjust_tsc_offset = svm_adjust_tsc_offset, | ||
3679 | |||
3680 | .set_tdp_cr3 = set_tdp_cr3, | ||
3522 | }; | 3681 | }; |
3523 | 3682 | ||
3524 | static int __init svm_init(void) | 3683 | static int __init svm_init(void) |