Skip to content

Commit

Permalink
kvm: Check irqchip mode before assign irqfd
Browse files Browse the repository at this point in the history
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 <[email protected]>
CC: Radim Krčmář <[email protected]>
CC: Alex Williamson <[email protected]>
CC: Eduardo Habkost <[email protected]>
Signed-off-by: Peter Xu <[email protected]>
Cc: [email protected]
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
xzpeter authored and VictorNogueiraRio committed Aug 11, 2019
1 parent 6bd2f13 commit 5ecb846
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 0 deletions.
7 changes: 7 additions & 0 deletions arch/x86/kvm/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,10 @@ void __kvm_migrate_timers(struct kvm_vcpu *vcpu)
__kvm_migrate_apic_timer(vcpu);
__kvm_migrate_pit_timer(vcpu);
}

bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
{
bool resample = args->flags & KVM_IRQFD_FLAG_RESAMPLE;

return resample ? irqchip_kernel(kvm) : irqchip_in_kernel(kvm);
}
1 change: 1 addition & 0 deletions arch/x86/kvm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ static inline int irqchip_in_kernel(struct kvm *kvm)
return mode != KVM_IRQCHIP_NONE;
}

bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args);
void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu);
void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu);
Expand Down
9 changes: 9 additions & 0 deletions virt/kvm/eventfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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_ACCOUNT);
if (!irqfd)
return -ENOMEM;
Expand Down

0 comments on commit 5ecb846

Please sign in to comment.