diff options
author | 2013-08-18 22:17:26 +0000 | |
---|---|---|
committer | 2013-08-18 22:17:26 +0000 | |
commit | 47ba5c79aa13c0e0128e13889584cae74d9d35ca (patch) | |
tree | ff8108936f786de84bdd2b8cee0c1092120ed6a6 | |
parent | Rework the DAE print routines again to output something closer to an actual (diff) | |
download | wireguard-openbsd-47ba5c79aa13c0e0128e13889584cae74d9d35ca.tar.xz wireguard-openbsd-47ba5c79aa13c0e0128e13889584cae74d9d35ca.zip |
data_access_emulation() may fault. Be sure to clear pcb_onfault before
invoking it.
While there, rework the return-to-pcb_onfault logic to avoid falling through
the DAE code. This allows us to get rid of the bogus DMT_SKIP flag as well:
DAE is only necessary if DMT_VALID is set in DMT0, and DMT0 is reset to zero
afterwards.
-rw-r--r-- | sys/arch/m88k/include/m88100.h | 7 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/m88100_machdep.c | 7 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/trap.c | 88 |
3 files changed, 52 insertions, 50 deletions
diff --git a/sys/arch/m88k/include/m88100.h b/sys/arch/m88k/include/m88100.h index dfcb71c0c87..7841b3e5ece 100644 --- a/sys/arch/m88k/include/m88100.h +++ b/sys/arch/m88k/include/m88100.h @@ -1,4 +1,4 @@ -/* $OpenBSD: m88100.h,v 1.7 2013/08/18 22:04:51 miod Exp $ */ +/* $OpenBSD: m88100.h,v 1.8 2013/08/18 22:17:26 miod Exp $ */ /* * Mach Operating System * Copyright (c) 1993-1992 Carnegie Mellon University @@ -34,12 +34,7 @@ /* * DMT0, DMT1, DMT2 layout - * - * The DMT_SKIP bit is never set by the cpu. It is used to mark 'known' - * transactions so that they don't get processed a second time by - * data_access_emulation(). */ -#define DMT_SKIP 0x00010000 /* skip this dmt */ #define DMT_BO 0x00008000 /* Byte-Ordering */ #define DMT_DAS 0x00004000 /* Data Access Space */ #define DMT_DOUB1 0x00002000 /* Double Word */ diff --git a/sys/arch/m88k/m88k/m88100_machdep.c b/sys/arch/m88k/m88k/m88100_machdep.c index 8384456aef1..9abb9426686 100644 --- a/sys/arch/m88k/m88k/m88100_machdep.c +++ b/sys/arch/m88k/m88k/m88100_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: m88100_machdep.c,v 1.9 2013/08/18 22:13:54 miod Exp $ */ +/* $OpenBSD: m88100_machdep.c,v 1.10 2013/08/18 22:17:26 miod Exp $ */ /* * Mach Operating System * Copyright (c) 1993-1991 Carnegie Mellon University @@ -153,8 +153,7 @@ data_access_emulation(u_int *f) { struct trapframe *eframe = (void *)f; - if (!ISSET(eframe->tf_dmt0, DMT_VALID) || - ISSET(eframe->tf_dmt0, DMT_SKIP)) + if (!ISSET(eframe->tf_dmt0, DMT_VALID)) return; dae_process(eframe, 0, @@ -164,7 +163,7 @@ data_access_emulation(u_int *f) dae_process(eframe, 2, eframe->tf_dma2, eframe->tf_dmd2, eframe->tf_dmt2); - eframe->tf_dmt0 |= DMT_SKIP; + eframe->tf_dmt0 = 0; } void diff --git a/sys/arch/m88k/m88k/trap.c b/sys/arch/m88k/m88k/trap.c index 5c09713e942..9881e063f9b 100644 --- a/sys/arch/m88k/m88k/trap.c +++ b/sys/arch/m88k/m88k/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.85 2013/04/12 04:48:52 miod Exp $ */ +/* $OpenBSD: trap.c,v 1.86 2013/08/18 22:17:26 miod Exp $ */ /* * Copyright (c) 2004, Miodrag Vallat. * Copyright (c) 1998 Steve Murphree, Jr. @@ -320,6 +320,7 @@ lose: fault_addr, frame, frame->tf_cpu); #endif + pcb_onfault = p->p_addr->u_pcb.pcb_onfault; switch (pbus_type) { case CMMU_PFSR_SUCCESS: /* @@ -327,33 +328,18 @@ lose: * to drain the data unit pipe line and reset dmt0 * so that trap won't get called again. */ + p->p_addr->u_pcb.pcb_onfault = 0; data_access_emulation((u_int *)frame); - frame->tf_dpfsr = 0; + p->p_addr->u_pcb.pcb_onfault = pcb_onfault; frame->tf_dmt0 = 0; + frame->tf_dpfsr = 0; KERNEL_UNLOCK(); return; case CMMU_PFSR_SFAULT: case CMMU_PFSR_PFAULT: - if ((pcb_onfault = p->p_addr->u_pcb.pcb_onfault) != 0) - p->p_addr->u_pcb.pcb_onfault = 0; + p->p_addr->u_pcb.pcb_onfault = 0; result = uvm_fault(map, va, VM_FAULT_INVALID, ftype); p->p_addr->u_pcb.pcb_onfault = pcb_onfault; - /* - * This could be a fault caused in copyout*() - * while accessing kernel space. - */ - if (result != 0 && pcb_onfault != 0) { - frame->tf_snip = pcb_onfault | NIP_V; - frame->tf_sfip = (pcb_onfault + 4) | FIP_V; - frame->tf_sxip = 0; - /* - * Continue as if the fault had been resolved, - * but do not try to complete the faulting - * access. - */ - frame->tf_dmt0 |= DMT_SKIP; - result = 0; - } if (result == 0) { /* * We could resolve the fault. Call @@ -361,9 +347,28 @@ lose: * unit pipe line and reset dmt0 so that trap * won't get called again. */ + p->p_addr->u_pcb.pcb_onfault = 0; data_access_emulation((u_int *)frame); + p->p_addr->u_pcb.pcb_onfault = pcb_onfault; + frame->tf_dmt0 = 0; frame->tf_dpfsr = 0; + KERNEL_UNLOCK(); + return; + } else if (pcb_onfault != 0) { + /* + * This could be a fault caused in copyout*() + * while accessing kernel space. + */ + frame->tf_snip = pcb_onfault | NIP_V; + frame->tf_sfip = (pcb_onfault + 4) | FIP_V; + frame->tf_sxip = 0; + /* + * Continue as if the fault had been resolved, + * but do not try to complete the faulting + * access. + */ frame->tf_dmt0 = 0; + frame->tf_dpfsr = 0; KERNEL_UNLOCK(); return; } @@ -434,22 +439,6 @@ user_fault: if (result == 0 && (caddr_t)va >= vm->vm_maxsaddr) uvm_grow(p, va); - /* - * This could be a fault caused in copyin*() - * while accessing user space. - */ - if (result != 0 && pcb_onfault != 0) { - frame->tf_snip = pcb_onfault | NIP_V; - frame->tf_sfip = (pcb_onfault + 4) | FIP_V; - frame->tf_sxip = 0; - /* - * Continue as if the fault had been resolved, but - * do not try to complete the faulting access. - */ - frame->tf_dmt0 |= DMT_SKIP; - result = 0; - } - if (result == 0) { if (type == T_INSTFLT + T_USER) { /* @@ -466,14 +455,33 @@ user_fault: * pipe line and reset dmt0 so that trap won't * get called again. */ + p->p_addr->u_pcb.pcb_onfault = 0; data_access_emulation((u_int *)frame); - frame->tf_dpfsr = 0; + p->p_addr->u_pcb.pcb_onfault = pcb_onfault; frame->tf_dmt0 = 0; + frame->tf_dpfsr = 0; } } else { - sig = result == EACCES ? SIGBUS : SIGSEGV; - fault_type = result == EACCES ? - BUS_ADRERR : SEGV_MAPERR; + /* + * This could be a fault caused in copyin*() + * while accessing user space. + */ + if (pcb_onfault != 0) { + frame->tf_snip = pcb_onfault | NIP_V; + frame->tf_sfip = (pcb_onfault + 4) | FIP_V; + frame->tf_sxip = 0; + /* + * Continue as if the fault had been resolved, + * but do not try to complete the faulting + * access. + */ + frame->tf_dmt0 = 0; + frame->tf_dpfsr = 0; + } else { + sig = result == EACCES ? SIGBUS : SIGSEGV; + fault_type = result == EACCES ? + BUS_ADRERR : SEGV_MAPERR; + } } KERNEL_UNLOCK(); break; |