Inform the guest introspection tool that an MSR is going to be changed. The kvmi_msr_event() function will check a bitmap of MSR-s of interest (configured via a KVMI_CONTROL_EVENTS(KVMI_MSR_CONTROL) request) and, if the new value differs from the previous one, it will generate a notification. The introspection tool can respond by allowing the guest to continue with normal execution or by discarding the change. This is meant to prevent malicious changes to MSR-s such as MSR_IA32_SYSENTER_EIP. The patch ensures that write access tracking of these MSR-s of interest is not disabled. Signed-off-by: Mihai Donțu <mdontu@xxxxxxxxxxxxxxx> Signed-off-by: Nicușor Cîțu <ncitu@xxxxxxxxxxxxxxx> --- arch/x86/kvm/svm.c | 5 +++++ arch/x86/kvm/vmx.c | 5 +++++ arch/x86/kvm/x86.c | 3 +++ 3 files changed, 13 insertions(+) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 766578401d1c..d6c7680e224b 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1066,6 +1066,11 @@ static void set_msr_interception(struct vcpu_svm *svm, unsigned long tmp; u32 offset; +#ifdef CONFIG_KVM_INTROSPECTION + if (!write && kvmi_monitored_msr(&svm->vcpu, msr)) + return; +#endif /* CONFIG_KVM_INTROSPECTION */ + /* * If this warning triggers extend the direct_access_msrs list at the * beginning of the file diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e9de89bd7f1c..fd92267a7a65 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5967,6 +5967,11 @@ static __always_inline void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, if (!cpu_has_vmx_msr_bitmap()) return; +#ifdef CONFIG_KVM_INTROSPECTION + if ((type & MSR_TYPE_W) && kvmi_monitored_msr(vcpu, msr)) + return; +#endif /* CONFIG_KVM_INTROSPECTION */ + if (static_branch_unlikely(&enable_evmcs)) evmcs_touch_msr_bitmap(); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f073fe596244..6ab052fdb786 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1301,6 +1301,9 @@ EXPORT_SYMBOL_GPL(kvm_enable_efer_bits); */ int kvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) { + if (!kvmi_msr_event(vcpu, msr)) + return 1; + switch (msr->index) { case MSR_FS_BASE: case MSR_GS_BASE: