diff options
author | Eric Sesterhenn <snakebyte@gmx.de> | 2006-02-01 06:06:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-01 11:53:21 -0500 |
commit | c5e3d98c5666c2533e67fb35dc5ad5de47db8aae (patch) | |
tree | 7423347a610ac84c80d340333ad4162fab895219 /arch | |
parent | 9a5e7339908d7d718ebc4149b77eee06291bdb95 (diff) |
[PATCH] alpha show_interrups() trashes argument
This is a bug found by cpminer. The show_interrupts function reuses i as a
for loop counter, and therefore trashes its contents, which are needed
later.
(akpm: rename local `i' to `irq', use for_each_inline_cpu())
Signed-off-by: Eric Sesterhenn <snakebyte@gmx.de>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/alpha/kernel/irq.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 76be5cf0de13..9006063e7369 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c | |||
@@ -68,34 +68,32 @@ show_interrupts(struct seq_file *p, void *v) | |||
68 | #ifdef CONFIG_SMP | 68 | #ifdef CONFIG_SMP |
69 | int j; | 69 | int j; |
70 | #endif | 70 | #endif |
71 | int i = *(loff_t *) v; | 71 | int irq = *(loff_t *) v; |
72 | struct irqaction * action; | 72 | struct irqaction * action; |
73 | unsigned long flags; | 73 | unsigned long flags; |
74 | 74 | ||
75 | #ifdef CONFIG_SMP | 75 | #ifdef CONFIG_SMP |
76 | if (i == 0) { | 76 | if (irq == 0) { |
77 | seq_puts(p, " "); | 77 | seq_puts(p, " "); |
78 | for (i = 0; i < NR_CPUS; i++) | 78 | for_each_online_cpu(j) |
79 | if (cpu_online(i)) | 79 | seq_printf(p, "CPU%d ", j); |
80 | seq_printf(p, "CPU%d ", i); | ||
81 | seq_putc(p, '\n'); | 80 | seq_putc(p, '\n'); |
82 | } | 81 | } |
83 | #endif | 82 | #endif |
84 | 83 | ||
85 | if (i < ACTUAL_NR_IRQS) { | 84 | if (irq < ACTUAL_NR_IRQS) { |
86 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 85 | spin_lock_irqsave(&irq_desc[irq].lock, flags); |
87 | action = irq_desc[i].action; | 86 | action = irq_desc[irq].action; |
88 | if (!action) | 87 | if (!action) |
89 | goto unlock; | 88 | goto unlock; |
90 | seq_printf(p, "%3d: ",i); | 89 | seq_printf(p, "%3d: ", irq); |
91 | #ifndef CONFIG_SMP | 90 | #ifndef CONFIG_SMP |
92 | seq_printf(p, "%10u ", kstat_irqs(i)); | 91 | seq_printf(p, "%10u ", kstat_irqs(irq)); |
93 | #else | 92 | #else |
94 | for (j = 0; j < NR_CPUS; j++) | 93 | for_each_online_cpu(j) |
95 | if (cpu_online(j)) | 94 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]); |
96 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | ||
97 | #endif | 95 | #endif |
98 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 96 | seq_printf(p, " %14s", irq_desc[irq].handler->typename); |
99 | seq_printf(p, " %c%s", | 97 | seq_printf(p, " %c%s", |
100 | (action->flags & SA_INTERRUPT)?'+':' ', | 98 | (action->flags & SA_INTERRUPT)?'+':' ', |
101 | action->name); | 99 | action->name); |
@@ -108,13 +106,12 @@ show_interrupts(struct seq_file *p, void *v) | |||
108 | 106 | ||
109 | seq_putc(p, '\n'); | 107 | seq_putc(p, '\n'); |
110 | unlock: | 108 | unlock: |
111 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 109 | spin_unlock_irqrestore(&irq_desc[irq].lock, flags); |
112 | } else if (i == ACTUAL_NR_IRQS) { | 110 | } else if (irq == ACTUAL_NR_IRQS) { |
113 | #ifdef CONFIG_SMP | 111 | #ifdef CONFIG_SMP |
114 | seq_puts(p, "IPI: "); | 112 | seq_puts(p, "IPI: "); |
115 | for (i = 0; i < NR_CPUS; i++) | 113 | for_each_online_cpu(j) |
116 | if (cpu_online(i)) | 114 | seq_printf(p, "%10lu ", cpu_data[j].ipi_count); |
117 | seq_printf(p, "%10lu ", cpu_data[i].ipi_count); | ||
118 | seq_putc(p, '\n'); | 115 | seq_putc(p, '\n'); |
119 | #endif | 116 | #endif |
120 | seq_printf(p, "ERR: %10lu\n", irq_err_count); | 117 | seq_printf(p, "ERR: %10lu\n", irq_err_count); |
@@ -122,7 +119,6 @@ unlock: | |||
122 | return 0; | 119 | return 0; |
123 | } | 120 | } |
124 | 121 | ||
125 | |||
126 | /* | 122 | /* |
127 | * handle_irq handles all normal device IRQ's (the special | 123 | * handle_irq handles all normal device IRQ's (the special |
128 | * SMP cross-CPU interrupts have their own specific | 124 | * SMP cross-CPU interrupts have their own specific |