git: ba28690cc6e0 - main - apple_bce: fix cold boot panic in mailbox send
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 06 Sep 2026 19:48:31 UTC
The branch main has been updated by seuros:
URL: https://cgit.FreeBSD.org/src/commit/?id=ba28690cc6e0ce6f418122d3db0b1eddec3d93a9
commit ba28690cc6e0ce6f418122d3db0b1eddec3d93a9
Author: Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-09-06 17:55:02 +0000
Commit: Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-09-06 19:47:44 +0000
apple_bce: fix cold boot panic in mailbox send
Poll mailbox reply registers with DELAY() when the system is still
cold, falling back to the interrupt-driven
sema_timedwait path once timers are available.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D58871
---
sys/dev/apple_bce/apple_bce_mailbox.c | 50 ++++++++++++++++++++++++++---------
1 file changed, 37 insertions(+), 13 deletions(-)
diff --git a/sys/dev/apple_bce/apple_bce_mailbox.c b/sys/dev/apple_bce/apple_bce_mailbox.c
index c19a01b7269c..deacb7ed5317 100644
--- a/sys/dev/apple_bce/apple_bce_mailbox.c
+++ b/sys/dev/apple_bce/apple_bce_mailbox.c
@@ -7,6 +7,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/sema.h>
@@ -62,20 +63,41 @@ bce_mailbox_send(struct bce_mailbox *mb, uint64_t msg, uint64_t *recv,
return (0);
}
- /* Wait for interrupt-driven reply */
- if (sema_timedwait(&mb->mb_cmpl, hz * timeout_ms / 1000) != 0) {
- /* Timeout -- reset to idle */
- atomic_store_int(&mb->status, 0);
- return (ETIMEDOUT);
- }
-
- if (atomic_load_int(&mb->status) != 2) {
- atomic_store_int(&mb->status, 0);
- return (ETIMEDOUT);
+ if (cold) {
+ /*
+ * During early boot, timer-backed sleeps are not available.
+ * Poll the hardware directly, but account for an installed
+ * interrupt handler consuming the reply first.
+ */
+ unsigned int waited = 0;
+
+ while (waited < timeout_ms * 1000) {
+ if (atomic_load_int(&mb->status) == 2)
+ break;
+ (void)bce_mailbox_handle_interrupt(mb);
+ if (atomic_load_int(&mb->status) == 2)
+ break;
+ DELAY(100);
+ waited += 100;
+ }
+ if (atomic_load_int(&mb->status) != 2) {
+ atomic_store_int(&mb->status, 0);
+ return (ETIMEDOUT);
+ }
+ } else {
+ /* Wait for interrupt-driven reply */
+ if (sema_timedwait(&mb->mb_cmpl,
+ hz * timeout_ms / 1000) != 0) {
+ atomic_store_int(&mb->status, 0);
+ return (ETIMEDOUT);
+ }
+ if (atomic_load_int(&mb->status) != 2) {
+ atomic_store_int(&mb->status, 0);
+ return (ETIMEDOUT);
+ }
}
- if (recv != NULL)
- *recv = mb->mb_result;
+ *recv = mb->mb_result;
atomic_store_int(&mb->status, 0);
return (0);
@@ -106,7 +128,9 @@ bce_mailbox_handle_interrupt(struct bce_mailbox *mb)
if (atomic_load_int(&mb->status) == 1) {
atomic_store_int(&mb->status, 2);
- sema_post(&mb->mb_cmpl);
+ /* A cold sender polls status and must not leave a token. */
+ if (!cold)
+ sema_post(&mb->mb_cmpl);
}
return (0);