Date: Tue, 1 Jun 2021 23:51:08 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 6cda62755612 - main - amd64: Relax the assertion added in commit 4a59cbc12 Message-ID: <202106012351.151Np83P020574@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=6cda62755612d706f30a99f70ff13ffa0f3f2422 commit 6cda62755612d706f30a99f70ff13ffa0f3f2422 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-06-01 23:38:09 +0000 Commit: Mark Johnston <markj@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202106012351.151Np83P020574>