kvm: svm: Intercept RDPRU
authorJim Mattson <jmattson@google.com>
Thu, 19 Sep 2019 22:59:17 +0000 (15:59 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 24 Sep 2019 14:15:36 +0000 (16:15 +0200)
The RDPRU instruction gives the guest read access to the IA32_APERF
MSR and the IA32_MPERF MSR. According to volume 3 of the APM, "When
virtualization is enabled, this instruction can be intercepted by the
Hypervisor. The intercept bit is at VMCB byte offset 10h, bit 14."
Since we don't enumerate the instruction in KVM_SUPPORTED_CPUID,
intercept it and synthesize #UD.

Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Drew Schmitt <dasch@google.com>
Reviewed-by: Jacob Xu <jacobhxu@google.com>
Reviewed-by: Peter Shier <pshier@google.com>
Reviewed-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/svm.h
arch/x86/include/uapi/asm/svm.h
arch/x86/kvm/svm.c

index dec9c1e84c78ea3ef5ab1717c05ec0178aad2d99..6ece8561ba661a8053cf045fd7f75267bf9d8d91 100644 (file)
@@ -52,6 +52,7 @@ enum {
        INTERCEPT_MWAIT,
        INTERCEPT_MWAIT_COND,
        INTERCEPT_XSETBV,
+       INTERCEPT_RDPRU,
 };
 
 
index a9731f8a480f3bca0785c94e870c74be6c191a67..2e8a30f06c74641cead87f4f460089f081c63ea7 100644 (file)
@@ -75,6 +75,7 @@
 #define SVM_EXIT_MWAIT         0x08b
 #define SVM_EXIT_MWAIT_COND    0x08c
 #define SVM_EXIT_XSETBV        0x08d
+#define SVM_EXIT_RDPRU         0x08e
 #define SVM_EXIT_NPF           0x400
 #define SVM_EXIT_AVIC_INCOMPLETE_IPI           0x401
 #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS     0x402
index ce75296b1b1073adf0d187ed12dcf7e592dea87c..f8ecb6df5106641517a75380e4755dfa65967f08 100644 (file)
@@ -1540,6 +1540,7 @@ static void init_vmcb(struct vcpu_svm *svm)
        set_intercept(svm, INTERCEPT_SKINIT);
        set_intercept(svm, INTERCEPT_WBINVD);
        set_intercept(svm, INTERCEPT_XSETBV);
+       set_intercept(svm, INTERCEPT_RDPRU);
        set_intercept(svm, INTERCEPT_RSM);
 
        if (!kvm_mwait_in_guest(svm->vcpu.kvm)) {
@@ -3832,6 +3833,12 @@ static int xsetbv_interception(struct vcpu_svm *svm)
        return 1;
 }
 
+static int rdpru_interception(struct vcpu_svm *svm)
+{
+       kvm_queue_exception(&svm->vcpu, UD_VECTOR);
+       return 1;
+}
+
 static int task_switch_interception(struct vcpu_svm *svm)
 {
        u16 tss_selector;
@@ -4783,6 +4790,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
        [SVM_EXIT_MONITOR]                      = monitor_interception,
        [SVM_EXIT_MWAIT]                        = mwait_interception,
        [SVM_EXIT_XSETBV]                       = xsetbv_interception,
+       [SVM_EXIT_RDPRU]                        = rdpru_interception,
        [SVM_EXIT_NPF]                          = npf_interception,
        [SVM_EXIT_RSM]                          = rsm_interception,
        [SVM_EXIT_AVIC_INCOMPLETE_IPI]          = avic_incomplete_ipi_interception,