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