Skip to content

Commit 8153144

Browse files
Andy Rossnashif
authored andcommitted
kernel/fatal: Fatal errors must not be preempted
The code underneath z_fatal_error() (which is usually run in an exception context, but is not required to be) was running with interrupts enabled, which is a little surprising. The only bug present currently is that the CPU ID extracted for logging is subject to a race (i.e. it's possible but very unlikely that such a handler might migrate to another CPU after the error is flagged and log the wrong CPU ID), but in general users with custom error handlers are likely to be surprised when their dying threads gets preempted by other code before they can abort. Signed-off-by: Andy Ross <[email protected]>
1 parent 4b670bd commit 8153144

File tree

1 file changed

+6
-0
lines changed

1 file changed

+6
-0
lines changed

kernel/fatal.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ static inline int get_cpu(void)
9292

9393
void z_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
9494
{
95+
/* We can't allow this code to be preempted, but don't need to
96+
* synchronize between CPUs, so an arch-layer lock is
97+
* appropriate.
98+
*/
99+
unsigned int key = arch_irq_lock();
95100
struct k_thread *thread = k_current_get();
96101

97102
/* sanitycheck looks for the "ZEPHYR FATAL ERROR" string, don't
@@ -160,5 +165,6 @@ void z_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
160165
#endif /*CONFIG_ARCH_HAS_NESTED_EXCEPTION_DETECTION */
161166
}
162167

168+
arch_irq_unlock(key);
163169
k_thread_abort(thread);
164170
}

0 commit comments

Comments
 (0)