]> xenbits.xensource.com Git - xen.git/commitdiff
Fix IOAPIC S3 with interrupt remapping enabled
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Aug 2010 14:06:24 +0000 (15:06 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Aug 2010 14:06:24 +0000 (15:06 +0100)
In ioapic_suspend, it reads and saves ioapic RTEs. But when interrupt
remapping is enabled, io_apic_read will call io_apic_read_remap_rte to
convert remapped format interrupt to compatible format, this results
in 'dest' field may be changed in remap_entry_to_ioapic_rte. When in
ioapic_resume, it will write the saved RTEs with incorrect 'dest' to
interrupt remapping table.

Actually it needn't to convert RTEs regardless interrupt remapping is
enabled or not. It just needs to save and restore RTE values
directly. This patch just uses __io_apic_read and __io_apic_write,
which won't call Interrupt remapping functions to convert, to save and
restore RTEs in ioapic_suspend and ioapic_resume. Thus fix this issue.

Signed-off-by: Weidong Han <weidong.han@intel.com>
xen-unstable changeset:   01d185dab39e
xen-unstable date:        Fri Aug 13 14:57:35 2010 +0100

xen/arch/x86/io_apic.c

index 4fc461a95406a5e323c66d9c2b5495157c4819ff..74f3749906995defe47ef8eb6c829e5c66c0a506 100644 (file)
@@ -2093,8 +2093,8 @@ void ioapic_suspend(void)
     spin_lock_irqsave(&ioapic_lock, flags);
     for (apic = 0; apic < nr_ioapics; apic++) {
         for (i = 0; i < nr_ioapic_registers[apic]; i ++, entry ++ ) {
-            *(((int *)entry) + 1) = io_apic_read(apic, 0x11 + 2 * i);
-            *(((int *)entry) + 0) = io_apic_read(apic, 0x10 + 2 * i);
+            *(((int *)entry) + 1) = __io_apic_read(apic, 0x11 + 2 * i);
+            *(((int *)entry) + 0) = __io_apic_read(apic, 0x10 + 2 * i);
         }
     }
     spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -2109,14 +2109,14 @@ void ioapic_resume(void)
 
     spin_lock_irqsave(&ioapic_lock, flags);
     for (apic = 0; apic < nr_ioapics; apic++){
-        reg_00.raw = io_apic_read(apic, 0);
+        reg_00.raw = __io_apic_read(apic, 0);
         if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) {
             reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
-            io_apic_write(apic, 0, reg_00.raw);
+            __io_apic_write(apic, 0, reg_00.raw);
         }
         for (i = 0; i < nr_ioapic_registers[apic]; i++, entry++) {
-            io_apic_write(apic, 0x11+2*i, *(((int *)entry)+1));
-            io_apic_write(apic, 0x10+2*i, *(((int *)entry)+0));
+            __io_apic_write(apic, 0x11+2*i, *(((int *)entry)+1));
+            __io_apic_write(apic, 0x10+2*i, *(((int *)entry)+0));
         }
     }
     spin_unlock_irqrestore(&ioapic_lock, flags);