aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/xen.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/pci/xen.c')
-rw-r--r--arch/x86/pci/xen.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 1819a91bbb9f..c489ef2c1a39 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -23,6 +23,8 @@
23#include <xen/features.h> 23#include <xen/features.h>
24#include <xen/events.h> 24#include <xen/events.h>
25#include <asm/xen/pci.h> 25#include <asm/xen/pci.h>
26#include <asm/xen/cpuid.h>
27#include <asm/apic.h>
26#include <asm/i8259.h> 28#include <asm/i8259.h>
27 29
28static int xen_pcifront_enable_irq(struct pci_dev *dev) 30static int xen_pcifront_enable_irq(struct pci_dev *dev)
@@ -423,6 +425,28 @@ int __init pci_xen_init(void)
423 return 0; 425 return 0;
424} 426}
425 427
428#ifdef CONFIG_PCI_MSI
429void __init xen_msi_init(void)
430{
431 if (!disable_apic) {
432 /*
433 * If hardware supports (x2)APIC virtualization (as indicated
434 * by hypervisor's leaf 4) then we don't need to use pirqs/
435 * event channels for MSI handling and instead use regular
436 * APIC processing
437 */
438 uint32_t eax = cpuid_eax(xen_cpuid_base() + 4);
439
440 if (((eax & XEN_HVM_CPUID_X2APIC_VIRT) && x2apic_mode) ||
441 ((eax & XEN_HVM_CPUID_APIC_ACCESS_VIRT) && cpu_has_apic))
442 return;
443 }
444
445 x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
446 x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
447}
448#endif
449
426int __init pci_xen_hvm_init(void) 450int __init pci_xen_hvm_init(void)
427{ 451{
428 if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs)) 452 if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs))
@@ -437,8 +461,11 @@ int __init pci_xen_hvm_init(void)
437#endif 461#endif
438 462
439#ifdef CONFIG_PCI_MSI 463#ifdef CONFIG_PCI_MSI
440 x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs; 464 /*
441 x86_msi.teardown_msi_irq = xen_teardown_msi_irq; 465 * We need to wait until after x2apic is initialized
466 * before we can set MSI IRQ ops.
467 */
468 x86_platform.apic_post_init = xen_msi_init;
442#endif 469#endif
443 return 0; 470 return 0;
444} 471}