git: 6fa9c2b1d282 - main - arm64: close a race in SVE register management

Alan Cox <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a7f81ed.3e435.11f2b2f0__44158.5477836028$1786741247$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by alc:

URL: https://cgit.FreeBSD.org/src/commit/?id=6fa9c2b1d2824034268646e0744e5e010155ffaf

commit 6fa9c2b1d2824034268646e0744e5e010155ffaf
Author:     Alan Cox <[email protected]>
AuthorDate: 2026-08-07 21:51:04 +0000
Commit:     Alan Cox <[email protected]>
CommitDate: 2026-08-14 20:57:35 +0000

    arm64: close a race in SVE register management
    
    While testing an unrelated pmap change, D58708, that dramatically
    reduces the number of TLBI instructions performed, and likely the
    timing of unrelated events, I started seeing "Storing an invalid VFP
    state" panics in vfp_save_state_common().  However, the origin of this
    panic is elsewhere, in the else branch of sve_restore_state().
    Specifically, my pmap change seems to have increased the likelihood that
    the thread executing the else branch would be preempted by another
    thread between the critical_exit() inside the else branch's call to
    vfp_restore_state_common() and its own call to critical_enter().  Prior
    to expanding the scope of the else branch's critical section, the MPASS
    added by this change would fire, catching the problem at its source,
    rather than later in vfp_save_state_common().
    
    Assisted-by:    Claude Code (Opus 5)
    Reviewed by:    kib, markj
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D58723
---
 sys/arm64/arm64/vfp.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sys/arm64/arm64/vfp.c b/sys/arm64/arm64/vfp.c
index d4c0eacf690c..11faa4cc21cd 100644
--- a/sys/arm64/arm64/vfp.c
+++ b/sys/arm64/arm64/vfp.c
@@ -797,15 +797,17 @@ sve_restore_state(struct thread *td)
 
 		critical_exit();
 	} else {
+		critical_enter();
+
 		vfp_restore_state_common(td, curpcb->pcb_fpflags);
 
 		/* Enable SVE if it wasn't previously enabled */
 		if ((curpcb->pcb_fpflags & PCB_FP_SVEVALID) == 0) {
-			critical_enter();
+			MPASS(PCPU_GET(fpcurthread) == td);
 			sve_enable();
 			curpcb->pcb_fpflags |= PCB_FP_SVEVALID;
-			critical_exit();
 		}
+		critical_exit();
 	}
 
 	return (true);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.