From 9294141d70cffa82b955c1ae1aa1e6b47f414db1 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 17 Jun 2022 17:09:17 +0200 Subject: [PATCH] avr: fix race condition in stack write If an interrupt happens between the writes to SPL and SPH, the stack pointer is inconsistent and terrible things will happen. Therefore, disable interrupts while updating the stack pointer. Interrupts are restored _before_ the write to SPH. This is safe, because interrupts are re-enabled with a one cycle delay. The avr-gcc and Clang compilers do the same thing when they need to update the stack pointer. It's almost impossible to test for this bug, but it should make firmware just a little bit more reliable. --- src/internal/task/task_stack_avr.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/internal/task/task_stack_avr.S b/src/internal/task/task_stack_avr.S index 20f98990d..2cba528f2 100644 --- a/src/internal/task/task_stack_avr.S +++ b/src/internal/task/task_stack_avr.S @@ -72,7 +72,10 @@ tinygo_swapTask: std Y+1, r3 // Switch to the new stack pointer. + in r0, 0x3f ; SREG + cli out 0x3d, r24; SPL + out 0x3f, r0 ; SREG, restore interrupts (after the next instruction) out 0x3e, r25; SPH // Load saved register from the new stack.