]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/CpuDxe: Disable interrupt before restoring context
authorHeyi Guo <heyi.guo@linaro.org>
Thu, 24 Sep 2015 17:05:39 +0000 (17:05 +0000)
committerabiesheuvel <abiesheuvel@Edk2>
Thu, 24 Sep 2015 17:05:39 +0000 (17:05 +0000)
Interrupt must be disabled before we storing ELR and other system
registers, or else ELR will be overridden by interrupt reentrance.

This bug is critical as we may get occasional exception or dead loop
when interrupt reentrance occurs:

  After increasing SP ... Before popping out registers
Or
  After restoring ELR

The 1st circumstance could also be resolved by optimizing SP operation
(Pop out registers before adding SP back), but the 2nd could not be
resolved by disabling interrupt.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18538 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S

index 2682f4fe7515ee67aaf623f84cfe7c1c8de31a80..ca6c9a15229c0df4656e0dca6c43da1244f8034a 100644 (file)
@@ -358,6 +358,14 @@ ASM_PFX(AsmCommonExceptionEntry):
 #define REG_PAIR(REG1, REG2, OFFSET, CONTEXT_SIZE)    ldp  REG1, REG2, [sp, #(OFFSET-CONTEXT_SIZE)]\r
 #define REG_ONE(REG1, OFFSET, CONTEXT_SIZE)           ldur REG1, [sp, #(OFFSET-CONTEXT_SIZE)]\r
 \r
+  //\r
+  // Disable interrupt(IRQ and FIQ) before restoring context,\r
+  // or else the context will be corrupted by interrupt reentrance.\r
+  // Interrupt mask will be restored from spsr by hardware when we call eret\r
+  //\r
+  msr   daifset, #3\r
+  isb\r
+\r
   // Adjust SP to pop system registers\r
   add     sp, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)\r
   ALL_SYS_REGS\r