@@ -341,9 +341,13 @@ struct vmcb {
#define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
+#define SVM_EVTINJ_TYPE_RESV1 (1 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
+#define SVM_EVTINJ_TYPE_RESV5 (5 << SVM_EVTINJ_TYPE_SHIFT)
+#define SVM_EVTINJ_TYPE_RESV6 (6 << SVM_EVTINJ_TYPE_SHIFT)
+#define SVM_EVTINJ_TYPE_RESV7 (7 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_VALID (1 << 31)
#define SVM_EVTINJ_VALID_ERR (1 << 11)
@@ -212,6 +212,10 @@ static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu)
static bool nested_vmcb_check_controls(struct vmcb_control_area *control)
{
+ u8 vector;
+ u32 type;
+ bool valid;
+
if ((vmcb_is_intercept(control, INTERCEPT_VMRUN)) == 0)
return false;
@@ -222,6 +226,17 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control)
!npt_enabled)
return false;
+ valid = control->event_inj & SVM_EVTINJ_VALID;
+ type = control->event_inj & SVM_EVTINJ_TYPE_MASK;
+ if (valid && (type == SVM_EVTINJ_TYPE_RESV1 ||
+ type >= SVM_EVTINJ_TYPE_RESV5))
+ return false;
+
+ vector = control->event_inj & SVM_EVTINJ_VEC_MASK;
+ if (valid && type == SVM_EVTINJ_TYPE_EXEPT &&
+ (vector == NMI_VECTOR || vector > 31))
+ return false;
+
return true;
}
According to sections "Canonicalization and Consistency Checks" and "Event Injection" in APM vol 2 VMRUN exits with VMEXIT_INVALID error code if either: - Reserved values of TYPE have been specified, or - TYPE = 3 (exception) has been specified with a vector that does not correspond to an exception (this includes vector 2, which is an NMI, not an exception). Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com> --- arch/x86/include/asm/svm.h | 4 ++++ arch/x86/kvm/svm/nested.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+)