From ee7554c1c4032d79b13d05172bb4a9b1338ae9fa Mon Sep 17 00:00:00 2001 From: Paul Guyot Date: Fri, 19 May 2023 19:01:41 +0200 Subject: [PATCH] esp_system: Fix a race-condition in esp_ipc_isr (in QEMU env) The race condition is very unlikely on real hardware but can be observed with qemu under heavy load. Also add missing `memw` instructions which are generated by the C compiler but absent in the assembly code. Signed-off-by: Paul Guyot Signed-off-by: KonstantinKondrashov Merges https://github.com/espressif/esp-idf/pull/11447 Closes https://github.com/espressif/esp-idf/issues/11433 --- components/esp_system/port/arch/xtensa/esp_ipc_isr.c | 2 ++ components/esp_system/port/arch/xtensa/esp_ipc_isr_handler.S | 2 ++ components/esp_system/port/arch/xtensa/esp_ipc_isr_routines.S | 1 + 3 files changed, 5 insertions(+) diff --git a/components/esp_system/port/arch/xtensa/esp_ipc_isr.c b/components/esp_system/port/arch/xtensa/esp_ipc_isr.c index 70fb1a9f1f..5ffcb76e21 100644 --- a/components/esp_system/port/arch/xtensa/esp_ipc_isr.c +++ b/components/esp_system/port/arch/xtensa/esp_ipc_isr.c @@ -142,6 +142,8 @@ void IRAM_ATTR esp_ipc_isr_release_other_cpu(void) const uint32_t cpu_id = xPortGetCoreID(); if (--s_count_of_nested_calls[cpu_id] == 0) { esp_ipc_isr_finish_cmd = 1; + // Make sure end flag is cleared and esp_ipc_isr_waiting_for_finish_cmd is done. + while (!esp_ipc_isr_end_fl) {}; IPC_ISR_EXIT_CRITICAL(); #if CONFIG_FREERTOS_SMP portRESTORE_INTERRUPTS(s_stored_interrupt_level); diff --git a/components/esp_system/port/arch/xtensa/esp_ipc_isr_handler.S b/components/esp_system/port/arch/xtensa/esp_ipc_isr_handler.S index 0fb4ae676a..20638a6895 100644 --- a/components/esp_system/port/arch/xtensa/esp_ipc_isr_handler.S +++ b/components/esp_system/port/arch/xtensa/esp_ipc_isr_handler.S @@ -96,6 +96,7 @@ esp_ipc_isr_handler: /* set the start flag */ movi a0, esp_ipc_isr_start_fl + memw s32i a0, a0, 0 /* Call the esp_ipc_function(void* arg) */ @@ -113,6 +114,7 @@ esp_ipc_isr_handler: /* set the end flag */ movi a0, esp_ipc_isr_end_fl + memw s32i a0, a0, 0 /* restore a0 */ diff --git a/components/esp_system/port/arch/xtensa/esp_ipc_isr_routines.S b/components/esp_system/port/arch/xtensa/esp_ipc_isr_routines.S index 01ddf8b528..e947c3ed2f 100644 --- a/components/esp_system/port/arch/xtensa/esp_ipc_isr_routines.S +++ b/components/esp_system/port/arch/xtensa/esp_ipc_isr_routines.S @@ -23,6 +23,7 @@ esp_ipc_isr_waiting_for_finish_cmd: /* waiting for the finish command */ .check_finish_cmd: + memw l32i a3, a2, 0 beqz a3, .check_finish_cmd ret