diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-11-06 16:16:56 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-11-06 16:32:19 -0700 |
commit | 0e4ccb1505a9e29c50170742ce26ac4655baab2d (patch) | |
tree | 59712adb4f49a554fb68178a2a6b1894ffbd1c42 /arch/x86/kernel/x86_init.c | |
parent | f92d74c1f5afaff7cd1ea14ade8f1ba6b519e422 (diff) | |
download | linux-0e4ccb1505a9e29c50170742ce26ac4655baab2d.tar.gz linux-0e4ccb1505a9e29c50170742ce26ac4655baab2d.tar.bz2 linux-0e4ccb1505a9e29c50170742ce26ac4655baab2d.zip |
PCI: Add x86_msi.msi_mask_irq() and msix_mask_irq()
Certain platforms do not allow writes in the MSI-X BARs to setup or tear
down vector values. To combat against the generic code trying to write to
that and either silently being ignored or crashing due to the pagetables
being marked R/O this patch introduces a platform override.
Note that we keep two separate, non-weak, functions default_mask_msi_irqs()
and default_mask_msix_irqs() for the behavior of the arch_mask_msi_irqs()
and arch_mask_msix_irqs(), as the default behavior is needed by x86 PCI
code.
For Xen, which does not allow the guest to write to MSI-X tables - as the
hypervisor is solely responsible for setting the vector values - we
implement two nops.
This fixes a Xen guest crash when passing a PCI device with MSI-X to the
guest. See the bugzilla for more details.
[bhelgaas: add bugzilla info]
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=64581
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
CC: Zhenzhong Duan <zhenzhong.duan@oracle.com>
Diffstat (limited to 'arch/x86/kernel/x86_init.c')
-rw-r--r-- | arch/x86/kernel/x86_init.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 8ce0072cd700..021783b1f46a 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -116,6 +116,8 @@ struct x86_msi_ops x86_msi = { .teardown_msi_irqs = default_teardown_msi_irqs, .restore_msi_irqs = default_restore_msi_irqs, .setup_hpet_msi = default_setup_hpet_msi, + .msi_mask_irq = default_msi_mask_irq, + .msix_mask_irq = default_msix_mask_irq, }; /* MSI arch specific hooks */ @@ -138,6 +140,14 @@ void arch_restore_msi_irqs(struct pci_dev *dev, int irq) { x86_msi.restore_msi_irqs(dev, irq); } +u32 arch_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) +{ + return x86_msi.msi_mask_irq(desc, mask, flag); +} +u32 arch_msix_mask_irq(struct msi_desc *desc, u32 flag) +{ + return x86_msi.msix_mask_irq(desc, flag); +} #endif struct x86_io_apic_ops x86_io_apic_ops = { |