diff options
Diffstat (limited to 'arch/x86/pci/xen.c')
-rw-r--r-- | arch/x86/pci/xen.c | 31 |
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 | ||
28 | static int xen_pcifront_enable_irq(struct pci_dev *dev) | 30 | static 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 | ||
429 | void __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 | |||
426 | int __init pci_xen_hvm_init(void) | 450 | int __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 | } |