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
This commit is contained in:
Andrew Turner 2024-10-24 10:52:37 +01:00
parent 6204391e99
commit a84653c5db
2 changed files with 11 additions and 2 deletions

View file

@ -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;

View file

@ -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