diff options
-rw-r--r-- | sys/x86/x86/msi.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/x86/x86/msi.c b/sys/x86/x86/msi.c index 20fda2cd58d5..19a427a9b628 100644 --- a/sys/x86/x86/msi.c +++ b/sys/x86/x86/msi.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/mutex.h> #include <sys/sx.h> +#include <sys/sysctl.h> #include <sys/systm.h> #include <x86/apicreg.h> #include <machine/cputypes.h> @@ -148,6 +149,16 @@ struct pic msi_pic = { .pic_reprogram_pin = NULL, }; +/* + * Xen hypervisors prior to 4.6.0 do not properly handle updates to + * enabled MSI-X table entries. Allow migration of MSI-X interrupts + * to be disabled via a tunable. + */ +static int msix_disable_migration = 0; +SYSCTL_INT(_machdep, OID_AUTO, disable_msix_migration, CTLFLAG_RDTUN, + &msix_disable_migration, 0, + "Disable migration of MSI-X interrupts between CPUs"); + static int msi_enabled; static int msi_last_irq; static struct mtx msi_lock; @@ -226,6 +237,9 @@ msi_assign_cpu(struct intsrc *isrc, u_int apic_id) if (msi->msi_first != msi) return (EINVAL); + if (msix_disable_migration && msi->msi_msix) + return (EINVAL); + /* Store information to free existing irq. */ old_vector = msi->msi_vector; old_id = msi->msi_cpu; |