summaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
authorPeter Xu <peterx@redhat.com>2019-05-05 16:56:42 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-16 08:22:15 +0200
commitd5f6539381c765291f96b744549b2dfb688a3f4a (patch)
tree345bbb5ed5cc3a7c9b1f7309da93737c84dccba0 /virt/kvm
parent90772cf588380e6253b8d820ed6c3a7933950181 (diff)
downloadlinux-stable-d5f6539381c765291f96b744549b2dfb688a3f4a.tar.gz
linux-stable-d5f6539381c765291f96b744549b2dfb688a3f4a.tar.bz2
linux-stable-d5f6539381c765291f96b744549b2dfb688a3f4a.zip
kvm: Check irqchip mode before assign irqfd
[ Upstream commit 654f1f13ea56b92bacade8ce2725aea0457f91c0 ] When assigning kvm irqfd we didn't check the irqchip mode but we allow KVM_IRQFD to succeed with all the irqchip modes. However it does not make much sense to create irqfd even without the kernel chips. Let's provide a arch-dependent helper to check whether a specific irqfd is allowed by the arch. At least for x86, it should make sense to check: - when irqchip mode is NONE, all irqfds should be disallowed, and, - when irqchip mode is SPLIT, irqfds that are with resamplefd should be disallowed. For either of the case, previously we'll silently ignore the irq or the irq ack event if the irqchip mode is incorrect. However that can cause misterious guest behaviors and it can be hard to triage. Let's fail KVM_IRQFD even earlier to detect these incorrect configurations. CC: Paolo Bonzini <pbonzini@redhat.com> CC: Radim Krčmář <rkrcmar@redhat.com> CC: Alex Williamson <alex.williamson@redhat.com> CC: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/eventfd.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index b20b751286fc..757a17f5ebde 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -44,6 +44,12 @@
static struct workqueue_struct *irqfd_cleanup_wq;
+bool __attribute__((weak))
+kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
+{
+ return true;
+}
+
static void
irqfd_inject(struct work_struct *work)
{
@@ -297,6 +303,9 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
if (!kvm_arch_intc_initialized(kvm))
return -EAGAIN;
+ if (!kvm_arch_irqfd_allowed(kvm, args))
+ return -EINVAL;
+
irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
if (!irqfd)
return -ENOMEM;