ArmPkg/ArmGicDxe: Fix double GIC EIOR write per interrupt

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>
This commit is contained in:
Alexei Fedorov 2016-08-08 15:46:00 +02:00 committed by Ard Biesheuvel
parent 87c400e14c
commit 7989300df7
2 changed files with 4 additions and 6 deletions

View File

@ -2,7 +2,7 @@
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR> Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR> Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR> Portions copyright (c) 2011-2016, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
@ -178,10 +178,9 @@ GicV2IrqInterruptHandler (
InterruptHandler (GicInterrupt, SystemContext); InterruptHandler (GicInterrupt, SystemContext);
} else { } else {
DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt)); DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
}
GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt); GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
} }
}
// //
// The protocol instance produced by this driver // The protocol instance produced by this driver

View File

@ -1,6 +1,6 @@
/** @file /** @file
* *
* Copyright (c) 2011-2015, ARM Limited. All rights reserved. * Copyright (c) 2011-2016, ARM Limited. All rights reserved.
* *
* This program and the accompanying materials * This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License * are licensed and made available under the terms and conditions of the BSD License
@ -169,10 +169,9 @@ GicV3IrqInterruptHandler (
InterruptHandler (GicInterrupt, SystemContext); InterruptHandler (GicInterrupt, SystemContext);
} else { } else {
DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt)); DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
}
GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt); GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);
} }
}
// //
// The protocol instance produced by this driver // The protocol instance produced by this driver