git: 2fd12bf2dd9c - main - amd64 resumectx(): restore FRED state before loading %cr4

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 29 Oct 2026 01:34:58 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=2fd12bf2dd9c1cf997ce2505bc2af10572ca70e2

commit 2fd12bf2dd9c1cf997ce2505bc2af10572ca70e2
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-28 14:05:50 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-10-29 01:33:47 +0000

    amd64 resumectx(): restore FRED state before loading %cr4
    
    %cr4 has the FRED enable bit. This only matters for NMI and #MC, and the
    kernel is really not ready to handle them while in resumectx(), but do
    it for formal correctness.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 sys/amd64/amd64/cpu_switch.S | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S
index 774098d7def5..47519c38b7ee 100644
--- a/sys/amd64/amd64/cpu_switch.S
+++ b/sys/amd64/amd64/cpu_switch.S
@@ -467,22 +467,10 @@ ENTRY(resumectx)
 	movl	PCB_SFMASK(%rdi),%eax
 	wrmsr
 
-	/* Restore CR0, CR2, CR4 and CR3. */
-	movq	PCB_CR0(%rdi),%rax
-	movq	%rax,%cr0
-	movq	PCB_CR2(%rdi),%rax
-	movq	%rax,%cr2
-	movq	PCB_CR4(%rdi),%rax
-	movq	%rax,%cr4
-	movq	PCB_CR3(%rdi),%rax
-	movq	%rax,%cr3
-
-	/* Restore descriptor tables. */
+	/* Restore FRED state before reloading %cr4. */
 	cmpb	$0,fred
-	jne	1f
-	lidt	PCB_IDT(%rdi)
-	jmp	2f
-1:	movl	$MSR_FRED_RSP0,%ecx
+	je	1f
+	movl	$MSR_FRED_RSP0,%ecx
 	movl	PCB_FRED_RSP0(%rdi),%eax
 	movl	4 + PCB_FRED_RSP0(%rdi),%edx
 	wrmsr
@@ -506,7 +494,22 @@ ENTRY(resumectx)
 	movl	PCB_FRED_CONFIG(%rdi),%eax
 	movl	4 + PCB_FRED_CONFIG(%rdi),%edx
 	wrmsr
-2:	lldt	PCB_LDT(%rdi)
+1:
+	/* Restore CR0, CR2, CR4 and CR3. */
+	movq	PCB_CR0(%rdi),%rax
+	movq	%rax,%cr0
+	movq	PCB_CR2(%rdi),%rax
+	movq	%rax,%cr2
+	movq	PCB_CR4(%rdi),%rax
+	movq	%rax,%cr4
+	movq	PCB_CR3(%rdi),%rax
+	movq	%rax,%cr3
+
+	/* Restore descriptor tables. */
+	cmpb	$0,fred
+	jne	1f
+	lidt	PCB_IDT(%rdi)
+1:	lldt	PCB_LDT(%rdi)
 
 #define	SDT_SYSTSS	9
 #define	SDT_SYSBSY	11