git: a84653c5db25 - main - arm64: Don't enable interrupts when in a spinlock
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 24 Oct 2024 10:36:38 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=a84653c5db255bf28c19b64dd6ac20009ebcbce3
commit a84653c5db255bf28c19b64dd6ac20009ebcbce3
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-10-24 09:52:37 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-10-24 10:20:48 +0000
arm64: Don't enable interrupts when in a spinlock
When we receive an exception while in a spinlock we shouldn't enable
interrupts. When entering a spinlock we disable interrupts so enabling
them here could cause surprising results.
The three cases that could cause this are:
1. A break-before-make sequence
2. Accessing possibly unmapped code with a fault handler
3. Buggy code
1 and 2 are supported later in the data abort handler, and 3 should be
fixed when found.
Reviewed by: mmel, kib, markj
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D46816
---
sys/arm64/arm64/trap.c | 12 ++++++++++--
sys/arm64/include/armreg.h | 1 +
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index d6e316e7ae0a..544189964ef0 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -308,10 +308,18 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
break;
}
}
- intr_enable();
+ if (td->td_md.md_spinlock_count == 0 &&
+ (frame->tf_spsr & PSR_DAIF_INTR) != PSR_DAIF_INTR) {
+ MPASS((frame->tf_spsr & PSR_DAIF_INTR) == 0);
+ intr_enable();
+ }
map = kernel_map;
} else {
- intr_enable();
+ if (td->td_md.md_spinlock_count == 0 &&
+ (frame->tf_spsr & PSR_DAIF_INTR) != PSR_DAIF_INTR) {
+ MPASS((frame->tf_spsr & PSR_DAIF_INTR) == 0);
+ intr_enable();
+ }
map = &td->td_proc->p_vmspace->vm_map;
if (map == NULL)
map = kernel_map;
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index e26f9859947e..5e87fafbec31 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -2569,6 +2569,7 @@
#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 (0)
+#define PSR_DAIF_INTR (PSR_I | PSR_F)
#define PSR_BTYPE 0x00000c00UL
#define PSR_SSBS 0x00001000UL
#define PSR_ALLINT 0x00002000UL