git: 8b6bbdb80fc0 - stable/14 - x86: Close race condition on MCA task queues at startup
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 09 Oct 2025 17:20:24 UTC
The branch stable/14 has been updated by jtl:
URL: https://cgit.FreeBSD.org/src/commit/?id=8b6bbdb80fc0c1d429320fa1c369df86b17c6a3e
commit 8b6bbdb80fc0c1d429320fa1c369df86b17c6a3e
Author: Jonathan T. Looney <jtl@FreeBSD.org>
AuthorDate: 2025-10-03 16:23:07 +0000
Commit: Jonathan T. Looney <jtl@FreeBSD.org>
CommitDate: 2025-10-09 17:20:06 +0000
x86: Close race condition on MCA task queues at startup
Currently, the CMCI handler checks the cold variable to determine
whether it can schedule a task. The task queue is setup as part of the
mca_startup() function, which is run well after the configure_final()
function sets the cold variable to 0. Therefore, if an MCA arrives
in the window between configure_final() and mca_startup() running,
the code could try to schedule a task on an unintitalized task queue.
Close the race by specifically checking whether the mca_startup()
function has run.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D12276
(cherry picked from commit 4a5d8670a7d58b04913fd90aae85a1e35236ca3d)
---
sys/x86/x86/mca.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sys/x86/x86/mca.c b/sys/x86/x86/mca.c
index 1851df8d00a0..933d10e52187 100644
--- a/sys/x86/x86/mca.c
+++ b/sys/x86/x86/mca.c
@@ -133,6 +133,7 @@ static struct taskqueue *mca_tq;
static struct task mca_resize_task;
static struct timeout_task mca_scan_task;
static struct mtx mca_lock;
+static bool mca_startup_done = false;
/* Statistics on number of MCA events by type, updated atomically. */
static uint64_t mca_stats[MCA_T_COUNT];
@@ -1025,7 +1026,7 @@ mca_process_records(enum scan_mode mode)
mtx_unlock_spin(&mca_lock);
if (mode == POLLED)
mca_resize_freelist();
- else if (!cold)
+ else if (mca_startup_done)
taskqueue_enqueue(mca_tq, &mca_resize_task);
}
@@ -1097,7 +1098,7 @@ sysctl_mca_maxcount(SYSCTL_HANDLER_ARGS)
doresize = true;
}
mtx_unlock_spin(&mca_lock);
- if (doresize && !cold)
+ if (doresize && mca_startup_done)
taskqueue_enqueue(mca_tq, &mca_resize_task);
return (error);
}
@@ -1115,6 +1116,7 @@ mca_startup(void *dummy)
taskqueue_start_threads(&mca_tq, 1, PI_SWI(SWI_TQ), "mca taskq");
taskqueue_enqueue_timeout_sbt(mca_tq, &mca_scan_task,
mca_ticks * SBT_1S, 0, C_PREL(1));
+ mca_startup_done = true;
}
SYSINIT(mca_startup, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, mca_startup, NULL);