]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmGicDxe: Fix double GIC EIOR write per interrupt
authorAlexei Fedorov <alexei.fedorov@arm.com>
Mon, 8 Aug 2016 13:46:00 +0000 (15:46 +0200)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Mon, 8 Aug 2016 13:46:00 +0000 (15:46 +0200)
This commit fixes a bug in the GIC v2 and v3 drivers where the GICC_EOIR
(End Of Interrupt Register) is written twice for a single interrupt.
GicV(2|3)IrqInterruptHandler() calls the Interrupt Handler and then
GicV(2|3)EndOfInterrupt() on exit:

 InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
 if (InterruptHandler != NULL) {
   // Call the registered interrupt handler.
   InterruptHandler (GicInterrupt, SystemContext);
 } else {
   DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
 }

 GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);

although gInterrupt->EndOfInterrupt() can be expected to have already
been called by InterruptHandler() [which is the case for the primary
in-tree handler in TimerDxe]

The fix moves the EndOfInterrupt() call inside the else case for
unregistered/spurious interrupts. This removes a potential race
condition that might have lost interrupts.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Alexei Fedorov <alexei.fedorov@arm.com>
Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c

index 036eb5cd6bf6845dd2b03b62c933c1dedaef7251..34d4be3867647e0fdad7356c949af8cd3ede7164 100644 (file)
@@ -2,7 +2,7 @@
 \r
 Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>\r
 Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>\r
-Portions copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR>\r
+Portions copyright (c) 2011-2016, ARM Ltd. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -178,9 +178,8 @@ GicV2IrqInterruptHandler (
     InterruptHandler (GicInterrupt, SystemContext);\r
   } else {\r
     DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));\r
+    GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);\r
   }\r
-\r
-  GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);\r
 }\r
 \r
 //\r
index 106c669fcb8777dfaad609c0ce9f5b572727a3ff..983936f3738a74bb5d5e08e012973df240958a8b 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
-*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2016, ARM Limited. All rights reserved.\r
 *\r
 *  This program and the accompanying materials\r
 *  are licensed and made available under the terms and conditions of the BSD License\r
@@ -169,9 +169,8 @@ GicV3IrqInterruptHandler (
     InterruptHandler (GicInterrupt, SystemContext);\r
   } else {\r
     DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));\r
+    GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);\r
   }\r
-\r
-  GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);\r
 }\r
 \r
 //\r