git: 4a5d8670a7d5 - main - x86: Close race condition on MCA task queues at startup

From: Jonathan T. Looney <jtl_at_FreeBSD.org>
Date: Mon, 06 Oct 2025 16:00:17 UTC
The branch main has been updated by jtl:

URL: https://cgit.FreeBSD.org/src/commit/?id=4a5d8670a7d58b04913fd90aae85a1e35236ca3d

commit 4a5d8670a7d58b04913fd90aae85a1e35236ca3d
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-06 15:59:31 +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
---
 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);