diff options
author | Han, Weidong <weidong.han@intel.com> | 2009-04-03 17:15:50 +0800 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-04-04 10:42:28 +0100 |
commit | d0b03bd1c6725a3463290d7f9626e4b583518a5a (patch) | |
tree | ce4ef17315c5435a8a77cd8fdb47e17193093349 | |
parent | 34aaaa948e3c9dd65b27fa499c5c9e8d8f1227cf (diff) | |
download | lwn-d0b03bd1c6725a3463290d7f9626e4b583518a5a.tar.gz lwn-d0b03bd1c6725a3463290d7f9626e4b583518a5a.zip |
x2apic/intr-remap: decouple interrupt remapping from x2apic
interrupt remapping must be enabled before enabling x2apic, but
interrupt remapping doesn't depend on x2apic, it can be used
separately. Enable interrupt remapping in init_dmars even x2apic
is not supported.
[dwmw2: Update Kconfig accordingly, fix build with INTR_REMAP && !X2APIC]
Signed-off-by: Weidong Han <weidong.han@intel.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | arch/x86/Kconfig | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/apic.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 29 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.c | 9 |
4 files changed, 35 insertions, 8 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3f27e5c0c9c9..229cf611d6ff 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -251,6 +251,7 @@ config SMP config X86_X2APIC bool "Support x2apic" depends on X86_LOCAL_APIC && X86_64 + select INTR_REMAP ---help--- This enables x2apic support on CPUs that have this feature. @@ -1879,7 +1880,6 @@ config DMAR_FLOPPY_WA config INTR_REMAP bool "Support for Interrupt Remapping (EXPERIMENTAL)" depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL - select X86_X2APIC ---help--- Supports Interrupt remapping for IO-APIC and MSI devices. To use x2apic mode in the CPU's which support x2APIC enhancements or diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index f9f0866ed6f8..42f2f8377422 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -107,11 +107,10 @@ extern u32 native_safe_apic_wait_icr_idle(void); extern void native_apic_icr_write(u32 low, u32 id); extern u64 native_apic_icr_read(void); -#ifdef CONFIG_X86_X2APIC - #define EIM_8BIT_APIC_ID 0 #define EIM_32BIT_APIC_ID 1 +#ifdef CONFIG_X86_X2APIC /* * Make previous memory operations globally visible before * sending the IPI through x2apic wrmsr. We need a serializing instruction or diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 0ad3fe77641a..767fe7e46d68 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2524,7 +2524,7 @@ static void irq_complete_move(struct irq_desc **descp) static inline void irq_complete_move(struct irq_desc **descp) {} #endif -#ifdef CONFIG_INTR_REMAP +#ifdef CONFIG_X86_X2APIC static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) { int apic, pin; @@ -2569,7 +2569,6 @@ static void ack_x2apic_edge(unsigned int irq) { ack_x2APIC_irq(); } - #endif static void ack_apic_edge(unsigned int irq) @@ -2680,6 +2679,26 @@ static void ack_apic_level(unsigned int irq) #endif } +#ifdef CONFIG_INTR_REMAP +static void ir_ack_apic_edge(unsigned int irq) +{ +#ifdef CONFIG_X86_X2APIC + if (x2apic_enabled()) + return ack_x2apic_edge(irq); +#endif + return ack_apic_edge(irq); +} + +static void ir_ack_apic_level(unsigned int irq) +{ +#ifdef CONFIG_X86_X2APIC + if (x2apic_enabled()) + return ack_x2apic_level(irq); +#endif + return ack_apic_level(irq); +} +#endif /* CONFIG_INTR_REMAP */ + static struct irq_chip ioapic_chip __read_mostly = { .name = "IO-APIC", .startup = startup_ioapic_irq, @@ -2699,8 +2718,8 @@ static struct irq_chip ir_ioapic_chip __read_mostly = { .mask = mask_IO_APIC_irq, .unmask = unmask_IO_APIC_irq, #ifdef CONFIG_INTR_REMAP - .ack = ack_x2apic_edge, - .eoi = ack_x2apic_level, + .ack = ir_ack_apic_edge, + .eoi = ir_ack_apic_level, #ifdef CONFIG_SMP .set_affinity = set_ir_ioapic_affinity_irq, #endif @@ -3426,7 +3445,7 @@ static struct irq_chip msi_ir_chip = { .unmask = unmask_msi_irq, .mask = mask_msi_irq, #ifdef CONFIG_INTR_REMAP - .ack = ack_x2apic_edge, + .ack = ir_ack_apic_edge, #ifdef CONFIG_SMP .set_affinity = ir_set_msi_irq_affinity, #endif diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index ef5795d0396b..f3eebd2b2d72 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1947,6 +1947,15 @@ static int __init init_dmars(void) } } +#ifdef CONFIG_INTR_REMAP + if (!intr_remapping_enabled) { + ret = enable_intr_remapping(0); + if (ret) + printk(KERN_ERR + "IOMMU: enable interrupt remapping failed\n"); + } +#endif + /* * For each rmrr * for each dev attached to rmrr |