diff options
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 93 |
1 files changed, 30 insertions, 63 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 475d1c948501..e32243eac2f4 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1084,7 +1084,6 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
1084 | if (npt_enabled) { | 1084 | if (npt_enabled) { |
1085 | /* Setup VMCB for Nested Paging */ | 1085 | /* Setup VMCB for Nested Paging */ |
1086 | control->nested_ctl = 1; | 1086 | control->nested_ctl = 1; |
1087 | clr_intercept(svm, INTERCEPT_TASK_SWITCH); | ||
1088 | clr_intercept(svm, INTERCEPT_INVLPG); | 1087 | clr_intercept(svm, INTERCEPT_INVLPG); |
1089 | clr_exception_intercept(svm, PF_VECTOR); | 1088 | clr_exception_intercept(svm, PF_VECTOR); |
1090 | clr_cr_intercept(svm, INTERCEPT_CR3_READ); | 1089 | clr_cr_intercept(svm, INTERCEPT_CR3_READ); |
@@ -1844,6 +1843,20 @@ static unsigned long nested_svm_get_tdp_cr3(struct kvm_vcpu *vcpu) | |||
1844 | return svm->nested.nested_cr3; | 1843 | return svm->nested.nested_cr3; |
1845 | } | 1844 | } |
1846 | 1845 | ||
1846 | static u64 nested_svm_get_tdp_pdptr(struct kvm_vcpu *vcpu, int index) | ||
1847 | { | ||
1848 | struct vcpu_svm *svm = to_svm(vcpu); | ||
1849 | u64 cr3 = svm->nested.nested_cr3; | ||
1850 | u64 pdpte; | ||
1851 | int ret; | ||
1852 | |||
1853 | ret = kvm_read_guest_page(vcpu->kvm, gpa_to_gfn(cr3), &pdpte, | ||
1854 | offset_in_page(cr3) + index * 8, 8); | ||
1855 | if (ret) | ||
1856 | return 0; | ||
1857 | return pdpte; | ||
1858 | } | ||
1859 | |||
1847 | static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu, | 1860 | static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu, |
1848 | unsigned long root) | 1861 | unsigned long root) |
1849 | { | 1862 | { |
@@ -1875,6 +1888,7 @@ static int nested_svm_init_mmu_context(struct kvm_vcpu *vcpu) | |||
1875 | 1888 | ||
1876 | vcpu->arch.mmu.set_cr3 = nested_svm_set_tdp_cr3; | 1889 | vcpu->arch.mmu.set_cr3 = nested_svm_set_tdp_cr3; |
1877 | vcpu->arch.mmu.get_cr3 = nested_svm_get_tdp_cr3; | 1890 | vcpu->arch.mmu.get_cr3 = nested_svm_get_tdp_cr3; |
1891 | vcpu->arch.mmu.get_pdptr = nested_svm_get_tdp_pdptr; | ||
1878 | vcpu->arch.mmu.inject_page_fault = nested_svm_inject_npf_exit; | 1892 | vcpu->arch.mmu.inject_page_fault = nested_svm_inject_npf_exit; |
1879 | vcpu->arch.mmu.shadow_root_level = get_npt_level(); | 1893 | vcpu->arch.mmu.shadow_root_level = get_npt_level(); |
1880 | vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu; | 1894 | vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu; |
@@ -2182,7 +2196,8 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
2182 | vmcb->control.exit_info_1, | 2196 | vmcb->control.exit_info_1, |
2183 | vmcb->control.exit_info_2, | 2197 | vmcb->control.exit_info_2, |
2184 | vmcb->control.exit_int_info, | 2198 | vmcb->control.exit_int_info, |
2185 | vmcb->control.exit_int_info_err); | 2199 | vmcb->control.exit_int_info_err, |
2200 | KVM_ISA_SVM); | ||
2186 | 2201 | ||
2187 | nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, &page); | 2202 | nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, &page); |
2188 | if (!nested_vmcb) | 2203 | if (!nested_vmcb) |
@@ -2894,15 +2909,20 @@ static int cr8_write_interception(struct vcpu_svm *svm) | |||
2894 | return 0; | 2909 | return 0; |
2895 | } | 2910 | } |
2896 | 2911 | ||
2912 | u64 svm_read_l1_tsc(struct kvm_vcpu *vcpu) | ||
2913 | { | ||
2914 | struct vmcb *vmcb = get_host_vmcb(to_svm(vcpu)); | ||
2915 | return vmcb->control.tsc_offset + | ||
2916 | svm_scale_tsc(vcpu, native_read_tsc()); | ||
2917 | } | ||
2918 | |||
2897 | static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | 2919 | static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) |
2898 | { | 2920 | { |
2899 | struct vcpu_svm *svm = to_svm(vcpu); | 2921 | struct vcpu_svm *svm = to_svm(vcpu); |
2900 | 2922 | ||
2901 | switch (ecx) { | 2923 | switch (ecx) { |
2902 | case MSR_IA32_TSC: { | 2924 | case MSR_IA32_TSC: { |
2903 | struct vmcb *vmcb = get_host_vmcb(svm); | 2925 | *data = svm->vmcb->control.tsc_offset + |
2904 | |||
2905 | *data = vmcb->control.tsc_offset + | ||
2906 | svm_scale_tsc(vcpu, native_read_tsc()); | 2926 | svm_scale_tsc(vcpu, native_read_tsc()); |
2907 | 2927 | ||
2908 | break; | 2928 | break; |
@@ -3314,8 +3334,6 @@ static int handle_exit(struct kvm_vcpu *vcpu) | |||
3314 | struct kvm_run *kvm_run = vcpu->run; | 3334 | struct kvm_run *kvm_run = vcpu->run; |
3315 | u32 exit_code = svm->vmcb->control.exit_code; | 3335 | u32 exit_code = svm->vmcb->control.exit_code; |
3316 | 3336 | ||
3317 | trace_kvm_exit(exit_code, vcpu, KVM_ISA_SVM); | ||
3318 | |||
3319 | if (!is_cr_intercept(svm, INTERCEPT_CR0_WRITE)) | 3337 | if (!is_cr_intercept(svm, INTERCEPT_CR0_WRITE)) |
3320 | vcpu->arch.cr0 = svm->vmcb->save.cr0; | 3338 | vcpu->arch.cr0 = svm->vmcb->save.cr0; |
3321 | if (npt_enabled) | 3339 | if (npt_enabled) |
@@ -3335,7 +3353,8 @@ static int handle_exit(struct kvm_vcpu *vcpu) | |||
3335 | svm->vmcb->control.exit_info_1, | 3353 | svm->vmcb->control.exit_info_1, |
3336 | svm->vmcb->control.exit_info_2, | 3354 | svm->vmcb->control.exit_info_2, |
3337 | svm->vmcb->control.exit_int_info, | 3355 | svm->vmcb->control.exit_int_info, |
3338 | svm->vmcb->control.exit_int_info_err); | 3356 | svm->vmcb->control.exit_int_info_err, |
3357 | KVM_ISA_SVM); | ||
3339 | 3358 | ||
3340 | vmexit = nested_svm_exit_special(svm); | 3359 | vmexit = nested_svm_exit_special(svm); |
3341 | 3360 | ||
@@ -3768,6 +3787,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
3768 | vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; | 3787 | vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; |
3769 | vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; | 3788 | vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; |
3770 | 3789 | ||
3790 | trace_kvm_exit(svm->vmcb->control.exit_code, vcpu, KVM_ISA_SVM); | ||
3791 | |||
3771 | if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI)) | 3792 | if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI)) |
3772 | kvm_before_handle_nmi(&svm->vcpu); | 3793 | kvm_before_handle_nmi(&svm->vcpu); |
3773 | 3794 | ||
@@ -3897,60 +3918,6 @@ static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) | |||
3897 | } | 3918 | } |
3898 | } | 3919 | } |
3899 | 3920 | ||
3900 | static const struct trace_print_flags svm_exit_reasons_str[] = { | ||
3901 | { SVM_EXIT_READ_CR0, "read_cr0" }, | ||
3902 | { SVM_EXIT_READ_CR3, "read_cr3" }, | ||
3903 | { SVM_EXIT_READ_CR4, "read_cr4" }, | ||
3904 | { SVM_EXIT_READ_CR8, "read_cr8" }, | ||
3905 | { SVM_EXIT_WRITE_CR0, "write_cr0" }, | ||
3906 | { SVM_EXIT_WRITE_CR3, "write_cr3" }, | ||
3907 | { SVM_EXIT_WRITE_CR4, "write_cr4" }, | ||
3908 | { SVM_EXIT_WRITE_CR8, "write_cr8" }, | ||
3909 | { SVM_EXIT_READ_DR0, "read_dr0" }, | ||
3910 | { SVM_EXIT_READ_DR1, "read_dr1" }, | ||
3911 | { SVM_EXIT_READ_DR2, "read_dr2" }, | ||
3912 | { SVM_EXIT_READ_DR3, "read_dr3" }, | ||
3913 | { SVM_EXIT_WRITE_DR0, "write_dr0" }, | ||
3914 | { SVM_EXIT_WRITE_DR1, "write_dr1" }, | ||
3915 | { SVM_EXIT_WRITE_DR2, "write_dr2" }, | ||
3916 | { SVM_EXIT_WRITE_DR3, "write_dr3" }, | ||
3917 | { SVM_EXIT_WRITE_DR5, "write_dr5" }, | ||
3918 | { SVM_EXIT_WRITE_DR7, "write_dr7" }, | ||
3919 | { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, | ||
3920 | { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, | ||
3921 | { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, | ||
3922 | { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, | ||
3923 | { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, | ||
3924 | { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, | ||
3925 | { SVM_EXIT_INTR, "interrupt" }, | ||
3926 | { SVM_EXIT_NMI, "nmi" }, | ||
3927 | { SVM_EXIT_SMI, "smi" }, | ||
3928 | { SVM_EXIT_INIT, "init" }, | ||
3929 | { SVM_EXIT_VINTR, "vintr" }, | ||
3930 | { SVM_EXIT_CPUID, "cpuid" }, | ||
3931 | { SVM_EXIT_INVD, "invd" }, | ||
3932 | { SVM_EXIT_HLT, "hlt" }, | ||
3933 | { SVM_EXIT_INVLPG, "invlpg" }, | ||
3934 | { SVM_EXIT_INVLPGA, "invlpga" }, | ||
3935 | { SVM_EXIT_IOIO, "io" }, | ||
3936 | { SVM_EXIT_MSR, "msr" }, | ||
3937 | { SVM_EXIT_TASK_SWITCH, "task_switch" }, | ||
3938 | { SVM_EXIT_SHUTDOWN, "shutdown" }, | ||
3939 | { SVM_EXIT_VMRUN, "vmrun" }, | ||
3940 | { SVM_EXIT_VMMCALL, "hypercall" }, | ||
3941 | { SVM_EXIT_VMLOAD, "vmload" }, | ||
3942 | { SVM_EXIT_VMSAVE, "vmsave" }, | ||
3943 | { SVM_EXIT_STGI, "stgi" }, | ||
3944 | { SVM_EXIT_CLGI, "clgi" }, | ||
3945 | { SVM_EXIT_SKINIT, "skinit" }, | ||
3946 | { SVM_EXIT_WBINVD, "wbinvd" }, | ||
3947 | { SVM_EXIT_MONITOR, "monitor" }, | ||
3948 | { SVM_EXIT_MWAIT, "mwait" }, | ||
3949 | { SVM_EXIT_XSETBV, "xsetbv" }, | ||
3950 | { SVM_EXIT_NPF, "npf" }, | ||
3951 | { -1, NULL } | ||
3952 | }; | ||
3953 | |||
3954 | static int svm_get_lpage_level(void) | 3921 | static int svm_get_lpage_level(void) |
3955 | { | 3922 | { |
3956 | return PT_PDPE_LEVEL; | 3923 | return PT_PDPE_LEVEL; |
@@ -4223,7 +4190,6 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
4223 | .get_mt_mask = svm_get_mt_mask, | 4190 | .get_mt_mask = svm_get_mt_mask, |
4224 | 4191 | ||
4225 | .get_exit_info = svm_get_exit_info, | 4192 | .get_exit_info = svm_get_exit_info, |
4226 | .exit_reasons_str = svm_exit_reasons_str, | ||
4227 | 4193 | ||
4228 | .get_lpage_level = svm_get_lpage_level, | 4194 | .get_lpage_level = svm_get_lpage_level, |
4229 | 4195 | ||
@@ -4239,6 +4205,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
4239 | .write_tsc_offset = svm_write_tsc_offset, | 4205 | .write_tsc_offset = svm_write_tsc_offset, |
4240 | .adjust_tsc_offset = svm_adjust_tsc_offset, | 4206 | .adjust_tsc_offset = svm_adjust_tsc_offset, |
4241 | .compute_tsc_offset = svm_compute_tsc_offset, | 4207 | .compute_tsc_offset = svm_compute_tsc_offset, |
4208 | .read_l1_tsc = svm_read_l1_tsc, | ||
4242 | 4209 | ||
4243 | .set_tdp_cr3 = set_tdp_cr3, | 4210 | .set_tdp_cr3 = set_tdp_cr3, |
4244 | 4211 | ||