Commit a76beb14 authored by Alex Williamson's avatar Alex Williamson Committed by Avi Kivity

KVM: Fix device assignment threaded irq handler

The kernel no longer allows us to pass NULL for the hard handler
without also specifying IRQF_ONESHOT.  IRQF_ONESHOT imposes latency
in the exit path that we don't need for MSI interrupts.  Long term
we'd like to inject these interrupts from the hard handler when
possible.  In the short term, we can create dummy hard handlers
that return us to the previous behavior.  Credit to Michael for
original patch.

Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=43328Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 055c9fa8
...@@ -334,6 +334,11 @@ static int assigned_device_enable_host_intx(struct kvm *kvm, ...@@ -334,6 +334,11 @@ static int assigned_device_enable_host_intx(struct kvm *kvm,
} }
#ifdef __KVM_HAVE_MSI #ifdef __KVM_HAVE_MSI
static irqreturn_t kvm_assigned_dev_msi(int irq, void *dev_id)
{
return IRQ_WAKE_THREAD;
}
static int assigned_device_enable_host_msi(struct kvm *kvm, static int assigned_device_enable_host_msi(struct kvm *kvm,
struct kvm_assigned_dev_kernel *dev) struct kvm_assigned_dev_kernel *dev)
{ {
...@@ -346,7 +351,7 @@ static int assigned_device_enable_host_msi(struct kvm *kvm, ...@@ -346,7 +351,7 @@ static int assigned_device_enable_host_msi(struct kvm *kvm,
} }
dev->host_irq = dev->dev->irq; dev->host_irq = dev->dev->irq;
if (request_threaded_irq(dev->host_irq, NULL, if (request_threaded_irq(dev->host_irq, kvm_assigned_dev_msi,
kvm_assigned_dev_thread_msi, 0, kvm_assigned_dev_thread_msi, 0,
dev->irq_name, dev)) { dev->irq_name, dev)) {
pci_disable_msi(dev->dev); pci_disable_msi(dev->dev);
...@@ -358,6 +363,11 @@ static int assigned_device_enable_host_msi(struct kvm *kvm, ...@@ -358,6 +363,11 @@ static int assigned_device_enable_host_msi(struct kvm *kvm,
#endif #endif
#ifdef __KVM_HAVE_MSIX #ifdef __KVM_HAVE_MSIX
static irqreturn_t kvm_assigned_dev_msix(int irq, void *dev_id)
{
return IRQ_WAKE_THREAD;
}
static int assigned_device_enable_host_msix(struct kvm *kvm, static int assigned_device_enable_host_msix(struct kvm *kvm,
struct kvm_assigned_dev_kernel *dev) struct kvm_assigned_dev_kernel *dev)
{ {
...@@ -374,7 +384,8 @@ static int assigned_device_enable_host_msix(struct kvm *kvm, ...@@ -374,7 +384,8 @@ static int assigned_device_enable_host_msix(struct kvm *kvm,
for (i = 0; i < dev->entries_nr; i++) { for (i = 0; i < dev->entries_nr; i++) {
r = request_threaded_irq(dev->host_msix_entries[i].vector, r = request_threaded_irq(dev->host_msix_entries[i].vector,
NULL, kvm_assigned_dev_thread_msix, kvm_assigned_dev_msix,
kvm_assigned_dev_thread_msix,
0, dev->irq_name, dev); 0, dev->irq_name, dev);
if (r) if (r)
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment