diff options
author | Andi Kleen <ak@suse.de> | 2006-12-06 20:14:07 -0500 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-12-06 20:14:07 -0500 |
commit | 516d2836434d279fef164bb1b964e83425d312d2 (patch) | |
tree | 924d47d91b7f75d407aa869dee2650102cc46a95 /arch/x86_64/kernel | |
parent | d15512f442ef1ea60f6195b0444fb27b3cf8d0e6 (diff) |
[PATCH] x86-64: Fix race in IO-APIC routing entry setup.
Interrupt could happen between setting the IO-APIC entry
and setting its interrupt data.
Pointed out by Linus.
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/kernel')
-rw-r--r-- | arch/x86_64/kernel/io_apic.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 88fcc4ebbf6e..eaf0b708e67d 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -174,14 +174,20 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) | |||
174 | * the interrupt, and we need to make sure the entry is fully populated | 174 | * the interrupt, and we need to make sure the entry is fully populated |
175 | * before that happens. | 175 | * before that happens. |
176 | */ | 176 | */ |
177 | static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | 177 | static void |
178 | __ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | ||
178 | { | 179 | { |
179 | unsigned long flags; | ||
180 | union entry_union eu; | 180 | union entry_union eu; |
181 | eu.entry = e; | 181 | eu.entry = e; |
182 | spin_lock_irqsave(&ioapic_lock, flags); | ||
183 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); | 182 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); |
184 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); | 183 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); |
184 | } | ||
185 | |||
186 | static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | ||
187 | { | ||
188 | unsigned long flags; | ||
189 | spin_lock_irqsave(&ioapic_lock, flags); | ||
190 | __ioapic_write_entry(apic, pin, e); | ||
185 | spin_unlock_irqrestore(&ioapic_lock, flags); | 191 | spin_unlock_irqrestore(&ioapic_lock, flags); |
186 | } | 192 | } |
187 | 193 | ||