diff options
author | Sheng Yang <sheng@linux.intel.com> | 2009-12-15 00:29:54 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:35:39 -0500 |
commit | 59708670b639bff00f92e519df1ae14da240e919 (patch) | |
tree | d13c81270cb94ce85e0d2cee773dbe62d7a9a79d | |
parent | 186a3e526ac1b4063a723f90ae4893beedb24fc6 (diff) |
KVM: VMX: Trap and invalid MWAIT/MONITOR instruction
We don't support these instructions, but guest can execute them even if the
feature('monitor') haven't been exposed in CPUID. So we would trap and inject
a #UD if guest try this way.
Cc: stable@kernel.org
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/include/asm/vmx.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 10 |
2 files changed, 11 insertions, 0 deletions
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 2b4945419a84..8f6b0111446a 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h | |||
@@ -251,6 +251,7 @@ enum vmcs_field { | |||
251 | #define EXIT_REASON_MSR_READ 31 | 251 | #define EXIT_REASON_MSR_READ 31 |
252 | #define EXIT_REASON_MSR_WRITE 32 | 252 | #define EXIT_REASON_MSR_WRITE 32 |
253 | #define EXIT_REASON_MWAIT_INSTRUCTION 36 | 253 | #define EXIT_REASON_MWAIT_INSTRUCTION 36 |
254 | #define EXIT_REASON_MONITOR_INSTRUCTION 39 | ||
254 | #define EXIT_REASON_PAUSE_INSTRUCTION 40 | 255 | #define EXIT_REASON_PAUSE_INSTRUCTION 40 |
255 | #define EXIT_REASON_MCE_DURING_VMENTRY 41 | 256 | #define EXIT_REASON_MCE_DURING_VMENTRY 41 |
256 | #define EXIT_REASON_TPR_BELOW_THRESHOLD 43 | 257 | #define EXIT_REASON_TPR_BELOW_THRESHOLD 43 |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index d4918d6fc924..8a8e13965076 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1224,6 +1224,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
1224 | CPU_BASED_USE_IO_BITMAPS | | 1224 | CPU_BASED_USE_IO_BITMAPS | |
1225 | CPU_BASED_MOV_DR_EXITING | | 1225 | CPU_BASED_MOV_DR_EXITING | |
1226 | CPU_BASED_USE_TSC_OFFSETING | | 1226 | CPU_BASED_USE_TSC_OFFSETING | |
1227 | CPU_BASED_MWAIT_EXITING | | ||
1228 | CPU_BASED_MONITOR_EXITING | | ||
1227 | CPU_BASED_INVLPG_EXITING; | 1229 | CPU_BASED_INVLPG_EXITING; |
1228 | opt = CPU_BASED_TPR_SHADOW | | 1230 | opt = CPU_BASED_TPR_SHADOW | |
1229 | CPU_BASED_USE_MSR_BITMAPS | | 1231 | CPU_BASED_USE_MSR_BITMAPS | |
@@ -3416,6 +3418,12 @@ static int handle_pause(struct kvm_vcpu *vcpu) | |||
3416 | return 1; | 3418 | return 1; |
3417 | } | 3419 | } |
3418 | 3420 | ||
3421 | static int handle_invalid_op(struct kvm_vcpu *vcpu) | ||
3422 | { | ||
3423 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
3424 | return 1; | ||
3425 | } | ||
3426 | |||
3419 | /* | 3427 | /* |
3420 | * The exit handlers return 1 if the exit was handled fully and guest execution | 3428 | * The exit handlers return 1 if the exit was handled fully and guest execution |
3421 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs | 3429 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs |
@@ -3453,6 +3461,8 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { | |||
3453 | [EXIT_REASON_EPT_VIOLATION] = handle_ept_violation, | 3461 | [EXIT_REASON_EPT_VIOLATION] = handle_ept_violation, |
3454 | [EXIT_REASON_EPT_MISCONFIG] = handle_ept_misconfig, | 3462 | [EXIT_REASON_EPT_MISCONFIG] = handle_ept_misconfig, |
3455 | [EXIT_REASON_PAUSE_INSTRUCTION] = handle_pause, | 3463 | [EXIT_REASON_PAUSE_INSTRUCTION] = handle_pause, |
3464 | [EXIT_REASON_MWAIT_INSTRUCTION] = handle_invalid_op, | ||
3465 | [EXIT_REASON_MONITOR_INSTRUCTION] = handle_invalid_op, | ||
3456 | }; | 3466 | }; |
3457 | 3467 | ||
3458 | static const int kvm_vmx_max_exit_handlers = | 3468 | static const int kvm_vmx_max_exit_handlers = |