git: d39f7430a6e1 - main - amd64: preserve %cr2 in NMI/MCE/DBG handlers.

Konstantin Belousov kib at FreeBSD.org
Sun Dec 27 11:14:58 UTC 2020


The branch main has been updated by kib:

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

commit d39f7430a6e1da419d6e4fb871bca5ba7863f738
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2020-12-25 21:58:43 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2020-12-27 10:59:33 +0000

    amd64: preserve %cr2 in NMI/MCE/DBG handlers.
    
    These handlers could interrupt code which has interrupts disabled,
    and if a spurious page fault occurs during exception handler run,
    we get clobbered %cr2 in higher level stack.
    
    This is mostly a speculation, but it is based on hints from good sources.
    
    MFC after:      1 week
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D27772
---
 sys/amd64/amd64/exception.S | 21 +++++++++++++++------
 sys/amd64/amd64/support.S   |  3 ++-
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 948f6c40e776..6b56a2c8a50e 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -667,9 +667,10 @@ IDTVEC(dbg)
 	jnz	dbg_fromuserspace
 	lfence
 	/*
-	 * We've interrupted the kernel.  Preserve GS.base in %r12,
-	 * %cr3 in %r13, and possibly lower half of MSR_IA32_SPEC_CTL in %r14d.
+	 * We've interrupted the kernel.  See comment in NMI handler about
+	 * registers use.
 	 */
+	movq	%cr2,%r15
 	movl	$MSR_GSBASE,%ecx
 	rdmsr
 	movq	%rax,%r12
@@ -710,6 +711,7 @@ IDTVEC(dbg)
 	shrq	$32,%rdx
 	wrmsr
 	movq	%r13,%cr3
+	movq	%r15,%cr2
 	RESTORE_REGS
 	addq	$TF_RIP,%rsp
 	jmp	doreti_iret
@@ -804,10 +806,14 @@ IDTVEC(nmi)
 	testb	$SEL_RPL_MASK,TF_CS(%rsp)
 	jnz	nmi_fromuserspace
 	/*
-	 * We've interrupted the kernel.  Preserve GS.base in %r12,
-	 * %cr3 in %r13, and possibly lower half of MSR_IA32_SPEC_CTL in %r14d.
+	 * We've interrupted the kernel.  Preserve in callee-saved regs:
+	 * GS.base in %r12,
+	 * %cr3 in %r13,
+	 * possibly lower half of MSR_IA32_SPEC_CTL in %r14d,
+	 * %cr2 in %r15.
 	 */
 	lfence
+	movq	%cr2,%r15
 	movl	$MSR_GSBASE,%ecx
 	rdmsr
 	movq	%rax,%r12
@@ -957,6 +963,7 @@ nocallchain:
 	je	2f
 	call	flush_l1d_sw		/* bhyve L1TF assist */
 2:	movq	%r13,%cr3
+	movq	%r15,%cr2
 	RESTORE_REGS
 	addq	$TF_RIP,%rsp
 	jmp	doreti_iret
@@ -1011,9 +1018,10 @@ IDTVEC(mchk)
 	testb	$SEL_RPL_MASK,TF_CS(%rsp)
 	jnz	mchk_fromuserspace
 	/*
-	 * We've interrupted the kernel.  Preserve GS.base in %r12,
-	 * %cr3 in %r13, and possibly lower half of MSR_IA32_SPEC_CTL in %r14d.
+	 * We've interrupted the kernel.  See comment in NMI handler about
+	 * registers use.
 	 */
+	movq	%cr2,%r15
 	movl	$MSR_GSBASE,%ecx
 	rdmsr
 	movq	%rax,%r12
@@ -1071,6 +1079,7 @@ mchk_calltrap:
 	shrq	$32,%rdx
 	wrmsr
 	movq	%r13,%cr3
+	movq	%r15,%cr2
 	RESTORE_REGS
 	addq	$TF_RIP,%rsp
 	jmp	doreti_iret
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
index 5a25dc1d9695..b0ef54a27ca1 100644
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -1651,7 +1651,8 @@ END(handle_ibrs_exit_rs)
  *
  * N.B. The function does not follow ABI calling conventions, it corrupts %rbx.
  * The vmm.ko caller expects that only %rax, %rdx, %rbx, %rcx, %r9, and %rflags
- * registers are clobbered.  The NMI handler caller only needs %r13 preserved.
+ * registers are clobbered.  The NMI handler caller only needs %r13 and %r15
+ * preserved.
  */
 ENTRY(flush_l1d_sw)
 #define	L1D_FLUSH_SIZE	(64 * 1024)


More information about the dev-commits-src-all mailing list