| d80b90ce | 08-Apr-2026 |
Akshay Belsare <akshay.belsare@amd.com> |
drivers: asu: guard wfe() with IRQ-mask check and add response timeout
The wfe()-based response loop in asu_update_queue_buffer_n_send_ipi() assumes THREAD_EXCP_NATIVE_INTR is clear at every call si
drivers: asu: guard wfe() with IRQ-mask check and add response timeout
The wfe()-based response loop in asu_update_queue_buffer_n_send_ipi() assumes THREAD_EXCP_NATIVE_INTR is clear at every call site. This does not hold during early boot: boot_init_primary_final() re-masks all exceptions including THREAD_EXCP_NATIVE_INTR at boot.c:1103 before calling thread_update_canaries() -> hw_get_random_bytes(). With PSTATE.I=1 the GIC cannot deliver SPI 89 (ASU doorbell), asu_resp_handler() never fires, sev() is never called, and wfe() blocks indefinitely.
Fix the response loop with two changes:
1. Arm a 2s safety timeout unconditionally before the loop so ASU firmware failures surface as TEE_ERROR_TARGET_DEAD rather than a silent hang.
2. Sample thread_get_exceptions() immediately before each wfe() call with no intervening code between the check and the instruction. This closes the TOCTOU window where the exception mask could change between a snapshot taken before the loop and the actual wfe(). - THREAD_EXCP_NATIVE_INTR clear (IRQs unmasked): wfe() yields the CPU; asu_resp_handler() fires sev() to wake it on response. - THREAD_EXCP_NATIVE_INTR set (IRQs masked): udelay(10) throttles the busy-poll, avoiding both a wfe() hang and uncontrolled bus hammering.
asu_resp_handler() retains its sev() call to support the wfe() path.
Fixes: 7f2d4e10736f ("drivers: amd: Add ASU support") Signed-off-by: Akshay Belsare <akshay.belsare@amd.com> Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
show more ...
|