diff --git a/arch/arm64/src/common/arm64_cpupause.c b/arch/arm64/src/common/arm64_cpupause.c index 37f118b84ac..27c892d7ce8 100644 --- a/arch/arm64/src/common/arm64_cpupause.c +++ b/arch/arm64/src/common/arm64_cpupause.c @@ -57,6 +57,7 @@ static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -135,6 +136,10 @@ int up_cpu_paused(int cpu) spin_unlock(&g_cpu_paused[cpu]); + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + /* Wait for the spinlock to be released. The requesting CPU will release * the spinlock when the CPU is resumed. */ @@ -163,6 +168,7 @@ int up_cpu_paused(int cpu) arm64_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -331,5 +337,12 @@ int up_cpu_resume(int cpu) !spin_islocked(&g_cpu_paused[cpu])); spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return OK; }