summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2013-08-18 22:17:26 +0000
committermiod <miod@openbsd.org>2013-08-18 22:17:26 +0000
commit47ba5c79aa13c0e0128e13889584cae74d9d35ca (patch)
treeff8108936f786de84bdd2b8cee0c1092120ed6a6
parentRework the DAE print routines again to output something closer to an actual (diff)
downloadwireguard-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.h7
-rw-r--r--sys/arch/m88k/m88k/m88100_machdep.c7
-rw-r--r--sys/arch/m88k/m88k/trap.c88
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;