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
This commit is contained in:
parent
60a38abb89
commit
6cda627556
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user