diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index bd94105f2960..9ece9a827a58 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -4777,20 +4777,22 @@ specify whether a certain MSR access should be explicitly filtered for or not. If this ioctl has never been invoked, MSR accesses are not guarded and the default KVM in-kernel emulation behavior is fully preserved. +Calling this ioctl with an empty set of ranges (all nmsrs == 0) disables MSR +filtering. In that mode, ``KVM_MSR_FILTER_DEFAULT_DENY`` is invalid and causes +an error. + As soon as the filtering is in place, every MSR access is processed through the filtering except for accesses to the x2APIC MSRs (from 0x800 to 0x8ff); x2APIC MSRs are always allowed, independent of the ``default_allow`` setting, and their behavior depends on the ``X2APIC_ENABLE`` bit of the APIC base register. -If a bit is within one of the defined ranges, read and write -accesses are guarded by the bitmap's value for the MSR index. If it is not -defined in any range, whether MSR access is rejected is determined by the flags -field in the kvm_msr_filter struct: ``KVM_MSR_FILTER_DEFAULT_ALLOW`` and -``KVM_MSR_FILTER_DEFAULT_DENY``. - -Calling this ioctl with an empty set of ranges (all nmsrs == 0) disables MSR -filtering. In that mode, KVM_MSR_FILTER_DEFAULT_DENY no longer has any effect. +If a bit is within one of the defined ranges, read and write accesses are +guarded by the bitmap's value for the MSR index if the kind of access +is included in the ``struct kvm_msr_filter_range`` flags. If no range +cover this particular access, the behavior is determined by the flags +field in the kvm_msr_filter struct: ``KVM_MSR_FILTER_DEFAULT_ALLOW`` +and ``KVM_MSR_FILTER_DEFAULT_DENY``. Each bitmap range specifies a range of MSRs to potentially allow access on. The range goes from MSR index [base .. base+nmsrs]. The flags field diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 08cfb5e4bd07..0f02d0fe3abb 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5252,14 +5252,21 @@ static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp) struct kvm_msr_filter filter; bool default_allow; int r = 0; + bool empty = true; u32 i; if (copy_from_user(&filter, user_msr_filter, sizeof(filter))) return -EFAULT; - kvm_clear_msr_filter(kvm); + for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) + empty &= !filter.ranges[i].nmsrs; default_allow = !(filter.flags & KVM_MSR_FILTER_DEFAULT_DENY); + if (empty && !default_allow) + return -EINVAL; + + kvm_clear_msr_filter(kvm); + kvm->arch.msr_filter.default_allow = default_allow; /*