diff options
| author | Yinghai Lu <yinghai@kernel.org> | 2008-12-26 05:05:47 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-12-27 07:24:00 -0500 |
| commit | 13a0c3c269b223f60abfac8a9811d77111a8b4ba (patch) | |
| tree | b57a92eb9eb7c8c1de30bbe29b6a461289e75c62 | |
| parent | 793f7b12a0c95e7bfec1badf9628043fb78fd440 (diff) | |
sparseirq: work around compiler optimizing away __weak functions
Impact: fix panic on null pointer with sparseirq
Some GCC versions seem to inline the weak global function,
when that function is empty.
Work it around, by making the functions return a (dummy) integer.
Signed-off-by: Yinghai <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | arch/x86/kernel/io_apic.c | 8 | ||||
| -rw-r--r-- | include/linux/irq.h | 6 | ||||
| -rw-r--r-- | init/main.c | 7 | ||||
| -rw-r--r-- | kernel/irq/handle.c | 7 |
4 files changed, 17 insertions, 11 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 2fe543f58ac8..976039377846 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c | |||
| @@ -170,7 +170,7 @@ static struct irq_cfg irq_cfgx[NR_IRQS] = { | |||
| 170 | [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, }, | 170 | [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, }, |
| 171 | }; | 171 | }; |
| 172 | 172 | ||
| 173 | void __init arch_early_irq_init(void) | 173 | int __init arch_early_irq_init(void) |
| 174 | { | 174 | { |
| 175 | struct irq_cfg *cfg; | 175 | struct irq_cfg *cfg; |
| 176 | struct irq_desc *desc; | 176 | struct irq_desc *desc; |
| @@ -184,6 +184,8 @@ void __init arch_early_irq_init(void) | |||
| 184 | desc = irq_to_desc(i); | 184 | desc = irq_to_desc(i); |
| 185 | desc->chip_data = &cfg[i]; | 185 | desc->chip_data = &cfg[i]; |
| 186 | } | 186 | } |
| 187 | |||
| 188 | return 0; | ||
| 187 | } | 189 | } |
| 188 | 190 | ||
| 189 | #ifdef CONFIG_SPARSE_IRQ | 191 | #ifdef CONFIG_SPARSE_IRQ |
| @@ -212,7 +214,7 @@ static struct irq_cfg *get_one_free_irq_cfg(int cpu) | |||
| 212 | return cfg; | 214 | return cfg; |
| 213 | } | 215 | } |
| 214 | 216 | ||
| 215 | void arch_init_chip_data(struct irq_desc *desc, int cpu) | 217 | int arch_init_chip_data(struct irq_desc *desc, int cpu) |
| 216 | { | 218 | { |
| 217 | struct irq_cfg *cfg; | 219 | struct irq_cfg *cfg; |
| 218 | 220 | ||
| @@ -224,6 +226,8 @@ void arch_init_chip_data(struct irq_desc *desc, int cpu) | |||
| 224 | BUG_ON(1); | 226 | BUG_ON(1); |
| 225 | } | 227 | } |
| 226 | } | 228 | } |
| 229 | |||
| 230 | return 0; | ||
| 227 | } | 231 | } |
| 228 | 232 | ||
| 229 | #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC | 233 | #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 69da275c0ebd..0e40af4bac40 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
| @@ -193,9 +193,9 @@ struct irq_desc { | |||
| 193 | const char *name; | 193 | const char *name; |
| 194 | } ____cacheline_internodealigned_in_smp; | 194 | } ____cacheline_internodealigned_in_smp; |
| 195 | 195 | ||
| 196 | extern void early_irq_init(void); | 196 | extern int early_irq_init(void); |
| 197 | extern void arch_early_irq_init(void); | 197 | extern int arch_early_irq_init(void); |
| 198 | extern void arch_init_chip_data(struct irq_desc *desc, int cpu); | 198 | extern int arch_init_chip_data(struct irq_desc *desc, int cpu); |
| 199 | extern void arch_init_copy_chip_data(struct irq_desc *old_desc, | 199 | extern void arch_init_copy_chip_data(struct irq_desc *old_desc, |
| 200 | struct irq_desc *desc, int cpu); | 200 | struct irq_desc *desc, int cpu); |
| 201 | extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc); | 201 | extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc); |
diff --git a/init/main.c b/init/main.c index c1f999a3cf31..c314aa15370e 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -539,13 +539,14 @@ void __init __weak thread_info_cache_init(void) | |||
| 539 | { | 539 | { |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | void __init __weak arch_early_irq_init(void) | 542 | int __init __weak arch_early_irq_init(void) |
| 543 | { | 543 | { |
| 544 | return 0; | ||
| 544 | } | 545 | } |
| 545 | 546 | ||
| 546 | void __init __weak early_irq_init(void) | 547 | int __init __weak early_irq_init(void) |
| 547 | { | 548 | { |
| 548 | arch_early_irq_init(); | 549 | return arch_early_irq_init(); |
| 549 | } | 550 | } |
| 550 | 551 | ||
| 551 | asmlinkage void __init start_kernel(void) | 552 | asmlinkage void __init start_kernel(void) |
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 893da67b7781..0bef3ecb7a0e 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
| @@ -86,8 +86,9 @@ void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr) | |||
| 86 | desc->kstat_irqs = (unsigned int *)ptr; | 86 | desc->kstat_irqs = (unsigned int *)ptr; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | void __attribute__((weak)) arch_init_chip_data(struct irq_desc *desc, int cpu) | 89 | int __weak arch_init_chip_data(struct irq_desc *desc, int cpu) |
| 90 | { | 90 | { |
| 91 | return 0; | ||
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) | 94 | static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) |
| @@ -132,7 +133,7 @@ static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_sm | |||
| 132 | /* FIXME: use bootmem alloc ...*/ | 133 | /* FIXME: use bootmem alloc ...*/ |
| 133 | static unsigned int kstat_irqs_legacy[NR_IRQS_LEGACY][NR_CPUS]; | 134 | static unsigned int kstat_irqs_legacy[NR_IRQS_LEGACY][NR_CPUS]; |
| 134 | 135 | ||
| 135 | void __init early_irq_init(void) | 136 | int __init early_irq_init(void) |
| 136 | { | 137 | { |
| 137 | struct irq_desc *desc; | 138 | struct irq_desc *desc; |
| 138 | int legacy_count; | 139 | int legacy_count; |
| @@ -151,7 +152,7 @@ void __init early_irq_init(void) | |||
| 151 | for (i = legacy_count; i < NR_IRQS; i++) | 152 | for (i = legacy_count; i < NR_IRQS; i++) |
| 152 | irq_desc_ptrs[i] = NULL; | 153 | irq_desc_ptrs[i] = NULL; |
| 153 | 154 | ||
| 154 | arch_early_irq_init(); | 155 | return arch_early_irq_init(); |
| 155 | } | 156 | } |
| 156 | 157 | ||
| 157 | struct irq_desc *irq_to_desc(unsigned int irq) | 158 | struct irq_desc *irq_to_desc(unsigned int irq) |
