Commit 0cb8410b authored by Jim Mattson's avatar Jim Mattson Committed by Paolo Bonzini

kvm: svm: Intercept RDPRU

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: default avatarJim Mattson <jmattson@google.com>
Reviewed-by: default avatarDrew Schmitt <dasch@google.com>
Reviewed-by: default avatarJacob Xu <jacobhxu@google.com>
Reviewed-by: default avatarPeter Shier <pshier@google.com>
Reviewed-by: default avatarKrish Sadhukhan <krish.sadhukhan@oracle.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a06dcd62
...@@ -52,6 +52,7 @@ enum { ...@@ -52,6 +52,7 @@ enum {
INTERCEPT_MWAIT, INTERCEPT_MWAIT,
INTERCEPT_MWAIT_COND, INTERCEPT_MWAIT_COND,
INTERCEPT_XSETBV, INTERCEPT_XSETBV,
INTERCEPT_RDPRU,
}; };
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#define SVM_EXIT_MWAIT 0x08b #define SVM_EXIT_MWAIT 0x08b
#define SVM_EXIT_MWAIT_COND 0x08c #define SVM_EXIT_MWAIT_COND 0x08c
#define SVM_EXIT_XSETBV 0x08d #define SVM_EXIT_XSETBV 0x08d
#define SVM_EXIT_RDPRU 0x08e
#define SVM_EXIT_NPF 0x400 #define SVM_EXIT_NPF 0x400
#define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 #define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401
#define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402
......
...@@ -1540,6 +1540,7 @@ static void init_vmcb(struct vcpu_svm *svm) ...@@ -1540,6 +1540,7 @@ static void init_vmcb(struct vcpu_svm *svm)
set_intercept(svm, INTERCEPT_SKINIT); set_intercept(svm, INTERCEPT_SKINIT);
set_intercept(svm, INTERCEPT_WBINVD); set_intercept(svm, INTERCEPT_WBINVD);
set_intercept(svm, INTERCEPT_XSETBV); set_intercept(svm, INTERCEPT_XSETBV);
set_intercept(svm, INTERCEPT_RDPRU);
set_intercept(svm, INTERCEPT_RSM); set_intercept(svm, INTERCEPT_RSM);
if (!kvm_mwait_in_guest(svm->vcpu.kvm)) { if (!kvm_mwait_in_guest(svm->vcpu.kvm)) {
...@@ -3832,6 +3833,12 @@ static int xsetbv_interception(struct vcpu_svm *svm) ...@@ -3832,6 +3833,12 @@ static int xsetbv_interception(struct vcpu_svm *svm)
return 1; 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) static int task_switch_interception(struct vcpu_svm *svm)
{ {
u16 tss_selector; u16 tss_selector;
...@@ -4783,6 +4790,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { ...@@ -4783,6 +4790,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_MONITOR] = monitor_interception, [SVM_EXIT_MONITOR] = monitor_interception,
[SVM_EXIT_MWAIT] = mwait_interception, [SVM_EXIT_MWAIT] = mwait_interception,
[SVM_EXIT_XSETBV] = xsetbv_interception, [SVM_EXIT_XSETBV] = xsetbv_interception,
[SVM_EXIT_RDPRU] = rdpru_interception,
[SVM_EXIT_NPF] = npf_interception, [SVM_EXIT_NPF] = npf_interception,
[SVM_EXIT_RSM] = rsm_interception, [SVM_EXIT_RSM] = rsm_interception,
[SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception, [SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment