diff --git a/core/arch/arm/include/kernel/thread.h b/core/arch/arm/include/kernel/thread.h index 297fe53fc50..cdc847c5c44 100644 --- a/core/arch/arm/include/kernel/thread.h +++ b/core/arch/arm/include/kernel/thread.h @@ -497,6 +497,8 @@ vaddr_t thread_stack_start(void); /* Returns the stack size for the current thread */ size_t thread_stack_size(void); +bool thread_is_in_normal_mode(void); + /* * Returns true if previous exeception also was in abort mode. * diff --git a/core/arch/arm/kernel/mutex.c b/core/arch/arm/kernel/mutex.c index 02446106721..b2bc13de66f 100644 --- a/core/arch/arm/kernel/mutex.c +++ b/core/arch/arm/kernel/mutex.c @@ -40,6 +40,7 @@ static void __mutex_lock(struct mutex *m, const char *fname, int lineno) { assert_have_no_spinlock(); assert(thread_get_id_may_fail() != -1); + assert(thread_is_in_normal_mode()); while (true) { uint32_t old_itr_status; diff --git a/core/arch/arm/kernel/thread.c b/core/arch/arm/kernel/thread.c index 0bd19100fcd..73b9181bb0c 100644 --- a/core/arch/arm/kernel/thread.c +++ b/core/arch/arm/kernel/thread.c @@ -654,6 +654,28 @@ bool thread_is_from_abort_mode(struct thread_abort_regs __maybe_unused *regs) #endif } +#ifdef ARM32 +bool thread_is_in_normal_mode(void) +{ + return (read_cpsr() & ARM32_CPSR_MODE_MASK) == ARM32_CPSR_MODE_SVC; +} +#endif + +#ifdef ARM64 +bool thread_is_in_normal_mode(void) +{ + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); + struct thread_core_local *l = thread_get_core_local(); + bool ret; + + /* If any bit in l->flags is set we're handling some exception. */ + ret = !l->flags; + thread_unmask_exceptions(exceptions); + + return ret; +} +#endif + void thread_state_free(void) { struct thread_core_local *l = thread_get_core_local();