Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: SVM: Intercept RDPMC

Intercept RDPMC and forward it to the PMU emulation code.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>

+15
+15
arch/x86/kvm/svm.c
··· 1014 1014 set_intercept(svm, INTERCEPT_NMI); 1015 1015 set_intercept(svm, INTERCEPT_SMI); 1016 1016 set_intercept(svm, INTERCEPT_SELECTIVE_CR0); 1017 + set_intercept(svm, INTERCEPT_RDPMC); 1017 1018 set_intercept(svm, INTERCEPT_CPUID); 1018 1019 set_intercept(svm, INTERCEPT_INVD); 1019 1020 set_intercept(svm, INTERCEPT_HLT); ··· 2771 2770 return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE; 2772 2771 } 2773 2772 2773 + static int rdpmc_interception(struct vcpu_svm *svm) 2774 + { 2775 + int err; 2776 + 2777 + if (!static_cpu_has(X86_FEATURE_NRIPS)) 2778 + return emulate_on_interception(svm); 2779 + 2780 + err = kvm_rdpmc(&svm->vcpu); 2781 + kvm_complete_insn_gp(&svm->vcpu, err); 2782 + 2783 + return 1; 2784 + } 2785 + 2774 2786 bool check_selective_cr0_intercepted(struct vcpu_svm *svm, unsigned long val) 2775 2787 { 2776 2788 unsigned long cr0 = svm->vcpu.arch.cr0; ··· 3204 3190 [SVM_EXIT_SMI] = nop_on_interception, 3205 3191 [SVM_EXIT_INIT] = nop_on_interception, 3206 3192 [SVM_EXIT_VINTR] = interrupt_window_interception, 3193 + [SVM_EXIT_RDPMC] = rdpmc_interception, 3207 3194 [SVM_EXIT_CPUID] = cpuid_interception, 3208 3195 [SVM_EXIT_IRET] = iret_interception, 3209 3196 [SVM_EXIT_INVD] = emulate_on_interception,