git: 9a83fcad145c - stable/13 - Enable arm64 SError exceptions in the kernel

Andrew Turner andrew at FreeBSD.org
Mon Sep 27 14:08:44 UTC 2021


The branch stable/13 has been updated by andrew:

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

commit 9a83fcad145c41d339e1ec07b405c54ae171341d
Author:     Andrew Turner <andrew at FreeBSD.org>
AuthorDate: 2021-08-09 16:30:44 +0000
Commit:     Andrew Turner <andrew at FreeBSD.org>
CommitDate: 2021-09-27 08:36:38 +0000

    Enable arm64 SError exceptions in the kernel
    
    These are needed to signal to the kernel when a Reliability,
    Availability, and Serviceability (RAS) exception has triggered.
    
    Reviewed by:    mhorne
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D31477
    
    (cherry picked from commit 17b6ee96138220a164d632f0be69d3df77bdd61a)
---
 sys/arm64/arm64/exception.S  | 24 ++++++++++++++----------
 sys/arm64/arm64/machdep.c    |  6 ++++++
 sys/arm64/arm64/vm_machdep.c |  4 ++--
 sys/arm64/include/armreg.h   |  8 ++------
 sys/arm64/include/cpufunc.h  |  7 +++++++
 5 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S
index 52586d9c225e..4fcf2ea6ece6 100644
--- a/sys/arm64/arm64/exception.S
+++ b/sys/arm64/arm64/exception.S
@@ -76,23 +76,25 @@ __FBSDID("$FreeBSD$");
 
 	ldr	x0, [x18, #(PC_CURTHREAD)]
 	bl	dbg_monitor_enter
-	msr	daifclr, #DAIF_D	/* Enable the debug exception */
-.endif
+
+	/* Unmask debug and SError exceptions */
+	msr	daifclr, #(DAIF_D | DAIF_A)
+.else
 	/*
+	 * Unmask debug and SError exceptions.
 	 * For EL1, debug exceptions are conditionally unmasked in
 	 * do_el1h_sync().
 	 */
+	msr	daifclr, #(DAIF_A)
+.endif
 .endm
 
 .macro	restore_registers el
-.if \el == 1
 	/*
-	 * Disable interrupts and debug exceptions, x18 may change in the
-	 * interrupt exception handler.  For EL0 exceptions, do_ast already
-	 * did this.
+	 * Mask all exceptions, x18 may change in the interrupt exception
+	 * handler.
 	 */
-	msr	daifset, #(DAIF_D | DAIF_INTR)
-.endif
+	msr	daifset, #(DAIF_ALL)
 .if \el == 0
 	ldr	x0, [x18, #PC_CURTHREAD]
 	mov	x1, sp
@@ -148,8 +150,10 @@ __FBSDID("$FreeBSD$");
 	/* Make sure the IRQs are enabled before calling ast() */
 	bic	x19, x19, #PSR_I
 1:
-	/* Disable interrupts */
-	msr	daifset, #(DAIF_D | DAIF_INTR)
+	/*
+	 * Mask interrupts while checking the ast pending flag
+	 */
+	msr	daifset, #(DAIF_INTR)
 
 	/* Read the current thread flags */
 	ldr	x1, [x18, #PC_CURTHREAD]	/* Load curthread */
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index a2db5e2b67af..1fbe3fbebb6f 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -931,6 +931,12 @@ init_proc0(vm_offset_t kstack)
 	thread0.td_pcb->pcb_vfpcpu = UINT_MAX;
 	thread0.td_frame = &proc0_tf;
 	pcpup->pc_curpcb = thread0.td_pcb;
+
+	/*
+	 * Unmask SError exceptions. They are used to signal a RAS failure,
+	 * or other hardware error.
+	 */
+	serror_enable();
 }
 
 typedef struct {
diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c
index b2ab8bb463b0..a8690eeb67da 100644
--- a/sys/arm64/arm64/vm_machdep.c
+++ b/sys/arm64/arm64/vm_machdep.c
@@ -114,7 +114,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
 
 	/* Setup to release spin count in fork_exit(). */
 	td2->td_md.md_spinlock_count = 1;
-	td2->td_md.md_saved_daif = td1->td_md.md_saved_daif & ~DAIF_I_MASKED;
+	td2->td_md.md_saved_daif = PSR_DAIF_DEFAULT;
 }
 
 void
@@ -186,7 +186,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
 
 	/* Setup to release spin count in fork_exit(). */
 	td->td_md.md_spinlock_count = 1;
-	td->td_md.md_saved_daif = td0->td_md.md_saved_daif & ~DAIF_I_MASKED;
+	td->td_md.md_saved_daif = PSR_DAIF_DEFAULT;
 }
 
 /*
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index b6acec3144fe..0057a353de66 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -124,12 +124,6 @@
 #define	CTR_ILINE_VAL(reg)	((reg) & CTR_ILINE_MASK)
 #define	CTR_ILINE_SIZE(reg)	(4 << (CTR_ILINE_VAL(reg) >> CTR_ILINE_SHIFT))
 
-/* DAIF - Interrupt Mask Bits */
-#define	DAIF_D_MASKED		(1 << 9)
-#define	DAIF_A_MASKED		(1 << 8)
-#define	DAIF_I_MASKED		(1 << 7)
-#define	DAIF_F_MASKED		(1 << 6)
-
 /* DAIFSet/DAIFClear */
 #define	DAIF_D			(1 << 3)
 #define	DAIF_A			(1 << 2)
@@ -1077,6 +1071,8 @@
 #define	PSR_A		0x00000100
 #define	PSR_D		0x00000200
 #define	PSR_DAIF	(PSR_D | PSR_A | PSR_I | PSR_F)
+/* The default DAIF mask. These bits are valid in spsr_el1 and daif */
+#define	PSR_DAIF_DEFAULT (PSR_F)
 #define	PSR_IL		0x00100000
 #define	PSR_SS		0x00200000
 #define	PSR_V		0x10000000
diff --git a/sys/arm64/include/cpufunc.h b/sys/arm64/include/cpufunc.h
index 7f13972e838b..94af62380de3 100644
--- a/sys/arm64/include/cpufunc.h
+++ b/sys/arm64/include/cpufunc.h
@@ -147,6 +147,13 @@ intr_enable(void)
 	__asm __volatile("msr daifclr, #(" __XSTRING(DAIF_INTR) ")");
 }
 
+static __inline void
+serror_enable(void)
+{
+
+	__asm __volatile("msr daifclr, #(" __XSTRING(DAIF_A) ")");
+}
+
 static __inline register_t
 get_midr(void)
 {


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