i386: write IO APIC irq routing entries in correct order

Since the "mask" bit is in the low word, when we write a new entry, we
need to write the high word first, before we potentially unmask it.

The exception is when we actually want to mask the interrupt, in which
case we want to write the low word first to make sure that the high word
doesn't change while the interrupt routing is still active.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+23 -3
+23 -3
arch/i386/kernel/io_apic.c
··· 147 147 return eu.entry; 148 148 } 149 149 150 + /* 151 + * When we write a new IO APIC routing entry, we need to write the high 152 + * word first! If the mask bit in the low word is clear, we will enable 153 + * the interrupt, and we need to make sure the entry is fully populated 154 + * before that happens. 155 + */ 150 156 static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) 151 157 { 152 158 unsigned long flags; 153 159 union entry_union eu; 154 160 eu.entry = e; 161 + spin_lock_irqsave(&ioapic_lock, flags); 162 + io_apic_write(apic, 0x11 + 2*pin, eu.w2); 163 + io_apic_write(apic, 0x10 + 2*pin, eu.w1); 164 + spin_unlock_irqrestore(&ioapic_lock, flags); 165 + } 166 + 167 + /* 168 + * When we mask an IO APIC routing entry, we need to write the low 169 + * word first, in order to set the mask bit before we change the 170 + * high bits! 171 + */ 172 + static void ioapic_mask_entry(int apic, int pin) 173 + { 174 + unsigned long flags; 175 + union entry_union eu = { .entry.mask = 1 }; 176 + 155 177 spin_lock_irqsave(&ioapic_lock, flags); 156 178 io_apic_write(apic, 0x10 + 2*pin, eu.w1); 157 179 io_apic_write(apic, 0x11 + 2*pin, eu.w2); ··· 296 274 /* 297 275 * Disable it in the IO-APIC irq-routing table: 298 276 */ 299 - memset(&entry, 0, sizeof(entry)); 300 - entry.mask = 1; 301 - ioapic_write_entry(apic, pin, entry); 277 + ioapic_mask_entry(apic, pin); 302 278 } 303 279 304 280 static void clear_IO_APIC (void)