]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: nSVM: Sanitize INT/EVENTINJ fields when copying from vmcb12
authorYosry Ahmed <yosry@kernel.org>
Tue, 3 Mar 2026 00:34:18 +0000 (00:34 +0000)
committerSean Christopherson <seanjc@google.com>
Thu, 5 Mar 2026 00:09:07 +0000 (16:09 -0800)
Make sure all fields used from vmcb12 in creating the vmcb02 are
sanitized, such that no unhandled or reserved bits end up in the vmcb02.

The following control fields are read from vmcb12 and have bits that are
either reserved or not handled/advertised by KVM: tlb_ctl, int_ctl,
int_state, int_vector, event_inj, misc_ctl, and misc_ctl2.

The following fields do not require any extra sanitizing:
- tlb_ctl: already being sanitized.
- int_ctl: bits from vmcb12 are copied bit-by-bit as needed.
- misc_ctl: only used in consistency checks (particularly NP_ENABLE).
- misc_ctl2: bits from vmcb12 are copied bit-by-bit as needed.

For the remaining fields (int_vector, int_state, and event_inj), make
sure only defined bits are copied from L1's vmcb12 into KVM'cache by
defining appropriate masks where needed.

Suggested-by: Jim Mattson <jmattson@google.com>
Signed-off-by: Yosry Ahmed <yosry@kernel.org>
Link: https://patch.msgid.link/20260303003421.2185681-25-yosry@kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/svm.h
arch/x86/kvm/svm/nested.c

index 16cf4f435aebd963fbaf03616eb7d1d30cc75949..bcfeb5e7c0edf26ec222d68fcefee76c566445ce 100644 (file)
@@ -224,6 +224,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
 #define X2APIC_MODE_SHIFT 30
 #define X2APIC_MODE_MASK (1 << X2APIC_MODE_SHIFT)
 
+#define SVM_INT_VECTOR_MASK GENMASK(7, 0)
+
 #define SVM_INTERRUPT_SHADOW_MASK      BIT_ULL(0)
 #define SVM_GUEST_INTERRUPT_MASK       BIT_ULL(1)
 
@@ -637,6 +639,9 @@ static inline void __unused_size_checks(void)
 #define SVM_EVTINJ_VALID (1 << 31)
 #define SVM_EVTINJ_VALID_ERR (1 << 11)
 
+#define SVM_EVTINJ_RESERVED_BITS ~(SVM_EVTINJ_VEC_MASK | SVM_EVTINJ_TYPE_MASK | \
+                                  SVM_EVTINJ_VALID_ERR | SVM_EVTINJ_VALID)
+
 #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
 #define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK
 
index c4680270e54f57bab03d8012a52910aab5e9a79e..bf1e1ca22d9cabf2bce6587da8ebefc7c24e1f7e 100644 (file)
@@ -488,18 +488,18 @@ void __nested_copy_vmcb_control_to_cache(struct kvm_vcpu *vcpu,
        to->tlb_ctl             = from->tlb_ctl & TLB_CONTROL_MASK;
        to->erap_ctl            = from->erap_ctl;
        to->int_ctl             = from->int_ctl;
-       to->int_vector          = from->int_vector;
-       to->int_state           = from->int_state;
+       to->int_vector          = from->int_vector & SVM_INT_VECTOR_MASK;
+       to->int_state           = from->int_state & SVM_INTERRUPT_SHADOW_MASK;
        to->exit_code           = from->exit_code;
        to->exit_info_1         = from->exit_info_1;
        to->exit_info_2         = from->exit_info_2;
        to->exit_int_info       = from->exit_int_info;
        to->exit_int_info_err   = from->exit_int_info_err;
-       to->event_inj           = from->event_inj;
+       to->event_inj           = from->event_inj & ~SVM_EVTINJ_RESERVED_BITS;
        to->event_inj_err       = from->event_inj_err;
        to->next_rip            = from->next_rip;
        to->nested_cr3          = from->nested_cr3;
-       to->misc_ctl2            = from->misc_ctl2;
+       to->misc_ctl2           = from->misc_ctl2;
        to->pause_filter_count  = from->pause_filter_count;
        to->pause_filter_thresh = from->pause_filter_thresh;