diff options
author | Yinghai Lu <yinghai@kernel.org> | 2008-12-05 21:58:33 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-08 08:31:54 -0500 |
commit | be5d5350a937cd8513b258739f1099420129e96f (patch) | |
tree | 9864a69da06dff2b4e0973d41d440c9d73fbc117 /arch | |
parent | 99d093d12897562a253540a902bbf65ec16042ac (diff) |
x86: MSI start irq numbering from nr_irqs_gsi
Impact: sanitize MSI irq number ordering from top-down to bottom-up
Increase new MSI IRQs starting from nr_irqs_gsi (which is somewhere below
256), instead of decreasing from NR_IRQS. (The latter method can result
in confusingly high IRQ numbers - if NR_CPUS is set to a high value and
NR_IRQS scales up to a high value.)
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/io_apic.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 2 |
3 files changed, 19 insertions, 9 deletions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 6afd9933a7dd..b35e94c2d6df 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h | |||
@@ -188,7 +188,7 @@ extern void restore_IO_APIC_setup(void); | |||
188 | extern void reinit_intr_remapped_IO_APIC(int); | 188 | extern void reinit_intr_remapped_IO_APIC(int); |
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | extern int probe_nr_irqs(void); | 191 | extern void probe_nr_irqs_gsi(void); |
192 | 192 | ||
193 | #else /* !CONFIG_X86_IO_APIC */ | 193 | #else /* !CONFIG_X86_IO_APIC */ |
194 | #define io_apic_assign_pci_irqs 0 | 194 | #define io_apic_assign_pci_irqs 0 |
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 9870461ae933..0dcde74abd1d 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c | |||
@@ -2973,7 +2973,7 @@ unsigned int create_irq_nr(unsigned int irq_want) | |||
2973 | 2973 | ||
2974 | irq = 0; | 2974 | irq = 0; |
2975 | spin_lock_irqsave(&vector_lock, flags); | 2975 | spin_lock_irqsave(&vector_lock, flags); |
2976 | for (new = irq_want; new > 0; new--) { | 2976 | for (new = irq_want; new < NR_IRQS; new++) { |
2977 | if (platform_legacy_irq(new)) | 2977 | if (platform_legacy_irq(new)) |
2978 | continue; | 2978 | continue; |
2979 | 2979 | ||
@@ -3001,11 +3001,14 @@ unsigned int create_irq_nr(unsigned int irq_want) | |||
3001 | return irq; | 3001 | return irq; |
3002 | } | 3002 | } |
3003 | 3003 | ||
3004 | static int nr_irqs_gsi = NR_IRQS_LEGACY; | ||
3004 | int create_irq(void) | 3005 | int create_irq(void) |
3005 | { | 3006 | { |
3007 | unsigned int irq_want; | ||
3006 | int irq; | 3008 | int irq; |
3007 | 3009 | ||
3008 | irq = create_irq_nr(nr_irqs - 1); | 3010 | irq_want = nr_irqs_gsi; |
3011 | irq = create_irq_nr(irq_want); | ||
3009 | 3012 | ||
3010 | if (irq == 0) | 3013 | if (irq == 0) |
3011 | irq = -1; | 3014 | irq = -1; |
@@ -3281,7 +3284,7 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc) | |||
3281 | int ret; | 3284 | int ret; |
3282 | unsigned int irq_want; | 3285 | unsigned int irq_want; |
3283 | 3286 | ||
3284 | irq_want = nr_irqs - 1; | 3287 | irq_want = nr_irqs_gsi; |
3285 | irq = create_irq_nr(irq_want); | 3288 | irq = create_irq_nr(irq_want); |
3286 | if (irq == 0) | 3289 | if (irq == 0) |
3287 | return -1; | 3290 | return -1; |
@@ -3321,11 +3324,11 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3321 | int index = 0; | 3324 | int index = 0; |
3322 | #endif | 3325 | #endif |
3323 | 3326 | ||
3324 | irq_want = nr_irqs - 1; | 3327 | irq_want = nr_irqs_gsi; |
3325 | sub_handle = 0; | 3328 | sub_handle = 0; |
3326 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 3329 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
3327 | irq = create_irq_nr(irq_want); | 3330 | irq = create_irq_nr(irq_want); |
3328 | irq_want--; | 3331 | irq_want++; |
3329 | if (irq == 0) | 3332 | if (irq == 0) |
3330 | return -1; | 3333 | return -1; |
3331 | #ifdef CONFIG_INTR_REMAP | 3334 | #ifdef CONFIG_INTR_REMAP |
@@ -3674,9 +3677,16 @@ int __init io_apic_get_redir_entries (int ioapic) | |||
3674 | return reg_01.bits.entries; | 3677 | return reg_01.bits.entries; |
3675 | } | 3678 | } |
3676 | 3679 | ||
3677 | int __init probe_nr_irqs(void) | 3680 | void __init probe_nr_irqs_gsi(void) |
3678 | { | 3681 | { |
3679 | return NR_IRQS; | 3682 | int idx; |
3683 | int nr = 0; | ||
3684 | |||
3685 | for (idx = 0; idx < nr_ioapics; idx++) | ||
3686 | nr += io_apic_get_redir_entries(idx) + 1; | ||
3687 | |||
3688 | if (nr > nr_irqs_gsi) | ||
3689 | nr_irqs_gsi = nr; | ||
3680 | } | 3690 | } |
3681 | 3691 | ||
3682 | /* -------------------------------------------------------------------------- | 3692 | /* -------------------------------------------------------------------------- |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 9d5674f7b6cc..a3834f123206 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -1082,7 +1082,7 @@ void __init setup_arch(char **cmdline_p) | |||
1082 | ioapic_init_mappings(); | 1082 | ioapic_init_mappings(); |
1083 | 1083 | ||
1084 | /* need to wait for io_apic is mapped */ | 1084 | /* need to wait for io_apic is mapped */ |
1085 | nr_irqs = probe_nr_irqs(); | 1085 | probe_nr_irqs_gsi(); |
1086 | 1086 | ||
1087 | kvm_guest_init(); | 1087 | kvm_guest_init(); |
1088 | 1088 | ||