git: 6cda62755612 - main - amd64: Relax the assertion added in commit 4a59cbc12
Mark Johnston
markj at FreeBSD.org
Tue Jun 1 23:51:09 UTC 2021
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=6cda62755612d706f30a99f70ff13ffa0f3f2422
commit 6cda62755612d706f30a99f70ff13ffa0f3f2422
Author: Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-06-01 23:38:09 +0000
Commit: Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-06-01 23:38:09 +0000
amd64: Relax the assertion added in commit 4a59cbc12
We only need to ensure that interrupts are disabled when handling a
fault from iret. Otherwise it's possible to trigger the assertion
legitimately, e.g., by copying in from an invalid address.
Fixes: 4a59cbc12
Reported by: pho
Reviewed by: kib
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D30594
---
sys/amd64/amd64/trap.c | 70 ++++++++++++++++++++++++++++++++------------------
1 file changed, 45 insertions(+), 25 deletions(-)
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index cc0b8fcf6c17..e67e188bb4fd 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -172,6 +172,39 @@ SYSCTL_INT(_machdep, OID_AUTO, nmi_flush_l1d_sw, CTLFLAG_RWTUN,
&nmi_flush_l1d_sw, 0,
"Flush L1 Data Cache on NMI exit, software bhyve L1TF mitigation assist");
+/*
+ * Table of handlers for various segment load faults.
+ */
+static const struct {
+ uintptr_t faddr;
+ uintptr_t fhandler;
+} sfhandlers[] = {
+ {
+ .faddr = (uintptr_t)ld_ds,
+ .fhandler = (uintptr_t)ds_load_fault,
+ },
+ {
+ .faddr = (uintptr_t)ld_es,
+ .fhandler = (uintptr_t)es_load_fault,
+ },
+ {
+ .faddr = (uintptr_t)ld_fs,
+ .fhandler = (uintptr_t)fs_load_fault,
+ },
+ {
+ .faddr = (uintptr_t)ld_gs,
+ .fhandler = (uintptr_t)gs_load_fault,
+ },
+ {
+ .faddr = (uintptr_t)ld_gsbase,
+ .fhandler = (uintptr_t)gsbase_load_fault
+ },
+ {
+ .faddr = (uintptr_t)ld_fsbase,
+ .fhandler = (uintptr_t)fsbase_load_fault,
+ },
+};
+
/*
* Exception, fault, and trap interface to the FreeBSD kernel.
* This common code is called from assembly language IDT gate entry
@@ -186,6 +219,7 @@ trap(struct trapframe *frame)
struct thread *td;
struct proc *p;
register_t addr, dr6;
+ size_t i;
int pf, signo, ucode;
u_int type;
@@ -450,9 +484,9 @@ trap(struct trapframe *frame)
* Magic '5' is the number of qwords occupied by
* the hardware trap frame.
*/
- KASSERT((read_rflags() & PSL_I) == 0,
- ("interrupts enabled"));
if (frame->tf_rip == (long)doreti_iret) {
+ KASSERT((read_rflags() & PSL_I) == 0,
+ ("interrupts enabled"));
frame->tf_rip = (long)doreti_iret_fault;
if ((PCPU_GET(curpmap)->pm_ucr3 !=
PMAP_NO_CR3) &&
@@ -463,30 +497,16 @@ trap(struct trapframe *frame)
}
return;
}
- if (frame->tf_rip == (long)ld_ds) {
- frame->tf_rip = (long)ds_load_fault;
- return;
- }
- if (frame->tf_rip == (long)ld_es) {
- frame->tf_rip = (long)es_load_fault;
- return;
- }
- if (frame->tf_rip == (long)ld_fs) {
- frame->tf_rip = (long)fs_load_fault;
- return;
- }
- if (frame->tf_rip == (long)ld_gs) {
- frame->tf_rip = (long)gs_load_fault;
- return;
- }
- if (frame->tf_rip == (long)ld_gsbase) {
- frame->tf_rip = (long)gsbase_load_fault;
- return;
- }
- if (frame->tf_rip == (long)ld_fsbase) {
- frame->tf_rip = (long)fsbase_load_fault;
- return;
+
+ for (i = 0; i < nitems(sfhandlers); i++) {
+ if (frame->tf_rip == sfhandlers[i].faddr) {
+ KASSERT((read_rflags() & PSL_I) == 0,
+ ("interrupts enabled"));
+ frame->tf_rip = sfhandlers[i].fhandler;
+ return;
+ }
}
+
if (curpcb->pcb_onfault != NULL) {
frame->tf_rip = (long)curpcb->pcb_onfault;
return;
More information about the dev-commits-src-main
mailing list