summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-10-28 10:18:54 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-10-28 10:18:54 +0000
commite702204f9ecfe0f56bae6b5a64cce8793abecf9a (patch)
tree829aab14d56590d10329da4956a0178084974799 /sys/arch
parenta4c86d54d6edd37a2146f78b94160cf49d162dec (diff)
When handling a userland data fault occuring in kernel mode, take the kernel
lock with KERNEL_LOCK, not KERNEL_PROC_LOCK. This lets bsd.mp run multiuser on a single-processor board.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/m88k/m88k/trap.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/sys/arch/m88k/m88k/trap.c b/sys/arch/m88k/m88k/trap.c
index ff37a4ac9a0..fda565353e8 100644
--- a/sys/arch/m88k/m88k/trap.c
+++ b/sys/arch/m88k/m88k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.40 2007/05/11 10:06:55 pedro Exp $ */
+/* $OpenBSD: trap.c,v 1.41 2007/10/28 10:18:53 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -264,7 +264,7 @@ m88100_trap(unsigned type, struct trapframe *frame)
/* data fault on the user address? */
if ((frame->tf_dmt0 & DMT_DAS) == 0) {
- type = T_DATAFLT + T_USER;
+ KERNEL_LOCK();
goto user_fault;
}
@@ -337,6 +337,7 @@ m88100_trap(unsigned type, struct trapframe *frame)
/* User mode instruction access fault */
/* FALLTHROUGH */
case T_DATAFLT+T_USER:
+ KERNEL_PROC_LOCK(p);
user_fault:
if (type == T_INSTFLT + T_USER) {
pbus_type = CMMU_PFSR_FAULT(frame->tf_ipfsr);
@@ -365,7 +366,6 @@ user_fault:
va = trunc_page((vaddr_t)fault_addr);
- KERNEL_PROC_LOCK(p);
vm = p->p_vmspace;
map = &vm->vm_map;
if ((pcb_onfault = p->p_addr->u_pcb.pcb_onfault) != 0)
@@ -392,7 +392,10 @@ user_fault:
else if (result == EACCES)
result = EFAULT;
}
- KERNEL_PROC_UNLOCK(p);
+ if (type == T_DATAFLT)
+ KERNEL_UNLOCK();
+ else
+ KERNEL_PROC_UNLOCK(p);
/*
* This could be a fault caused in copyin*()
@@ -411,7 +414,15 @@ user_fault:
}
if (result == 0) {
- if (type == T_DATAFLT+T_USER) {
+ if (type == T_INSTFLT + T_USER) {
+ /*
+ * back up SXIP, SNIP,
+ * clearing the Error bit
+ */
+ frame->tf_sfip = frame->tf_snip & ~FIP_E;
+ frame->tf_snip = frame->tf_sxip & ~NIP_E;
+ frame->tf_ipfsr = 0;
+ } else {
/*
* We could resolve the fault. Call
* data_access_emulation to drain the data unit
@@ -421,14 +432,6 @@ user_fault:
data_access_emulation((unsigned *)frame);
frame->tf_dpfsr = 0;
frame->tf_dmt0 = 0;
- } else {
- /*
- * back up SXIP, SNIP,
- * clearing the Error bit
- */
- frame->tf_sfip = frame->tf_snip & ~FIP_E;
- frame->tf_snip = frame->tf_sxip & ~NIP_E;
- frame->tf_ipfsr = 0;
}
} else {
sig = result == EACCES ? SIGBUS : SIGSEGV;