summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2002-09-29 02:48:37 +0000
committerjulian <julian@FreeBSD.org>2002-09-29 02:48:37 +0000
commit71a47fc4fb08b980b0f0c3fdb929b3fc75cdb355 (patch)
tree31b3ef73bd14b12bdfa2b01de4c71598d334fcc5 /sys/kern
parentf9ba7e0f17bbf4ca794a3182f8aab499de6f3cd4 (diff)
downloadFreeBSD-src-71a47fc4fb08b980b0f0c3fdb929b3fc75cdb355.zip
FreeBSD-src-71a47fc4fb08b980b0f0c3fdb929b3fc75cdb355.tar.gz
lock proc while calling psignal
(plus related cleanups) Submitted by: davidxu
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_kse.c26
-rw-r--r--sys/kern/kern_thread.c26
2 files changed, 34 insertions, 18 deletions
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c
index 5b34330..ede053c 100644
--- a/sys/kern/kern_kse.c
+++ b/sys/kern/kern_kse.c
@@ -326,6 +326,7 @@ thread_free(struct thread *td)
int
thread_export_context(struct thread *td)
{
+ struct proc *p = td->td_proc;
struct ksegrp *kg;
uintptr_t mbx;
void *addr;
@@ -346,7 +347,9 @@ thread_export_context(struct thread *td)
}
if (error) {
- psignal(td->td_proc, SIGSEGV);
+ PROC_LOCK(p);
+ psignal(p, SIGSEGV);
+ PROC_UNLOCK(p);
return (error);
}
/* get address in latest mbox of list pointer */
@@ -364,16 +367,18 @@ thread_export_context(struct thread *td)
for (;;) {
mbx = (uintptr_t)kg->kg_completed;
if (suword(addr, mbx)) {
- psignal(kg->kg_proc, SIGSEGV);
+ PROC_LOCK(p);
+ psignal(p, SIGSEGV);
+ PROC_UNLOCK(p);
return (EFAULT);
}
- PROC_LOCK(kg->kg_proc);
+ PROC_LOCK(p);
if (mbx == (uintptr_t)kg->kg_completed) {
kg->kg_completed = td->td_mailbox;
- PROC_UNLOCK(kg->kg_proc);
+ PROC_UNLOCK(p);
break;
}
- PROC_UNLOCK(kg->kg_proc);
+ PROC_UNLOCK(p);
}
return (0);
}
@@ -385,6 +390,7 @@ thread_export_context(struct thread *td)
static int
thread_link_mboxes(struct ksegrp *kg, struct kse *ke)
{
+ struct proc *p = kg->kg_proc;
void *addr;
uintptr_t mbx;
@@ -397,17 +403,19 @@ thread_link_mboxes(struct ksegrp *kg, struct kse *ke)
for (;;) {
mbx = (uintptr_t)kg->kg_completed;
if (suword(addr, mbx)) {
- psignal(kg->kg_proc, SIGSEGV);
+ PROC_LOCK(p);
+ psignal(p, SIGSEGV);
+ PROC_UNLOCK(p);
return (EFAULT);
}
/* XXXKSE could use atomic CMPXCH here */
- PROC_LOCK(kg->kg_proc);
+ PROC_LOCK(p);
if (mbx == (uintptr_t)kg->kg_completed) {
kg->kg_completed = NULL;
- PROC_UNLOCK(kg->kg_proc);
+ PROC_UNLOCK(p);
break;
}
- PROC_UNLOCK(kg->kg_proc);
+ PROC_UNLOCK(p);
}
return (0);
}
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 5b34330..ede053c 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -326,6 +326,7 @@ thread_free(struct thread *td)
int
thread_export_context(struct thread *td)
{
+ struct proc *p = td->td_proc;
struct ksegrp *kg;
uintptr_t mbx;
void *addr;
@@ -346,7 +347,9 @@ thread_export_context(struct thread *td)
}
if (error) {
- psignal(td->td_proc, SIGSEGV);
+ PROC_LOCK(p);
+ psignal(p, SIGSEGV);
+ PROC_UNLOCK(p);
return (error);
}
/* get address in latest mbox of list pointer */
@@ -364,16 +367,18 @@ thread_export_context(struct thread *td)
for (;;) {
mbx = (uintptr_t)kg->kg_completed;
if (suword(addr, mbx)) {
- psignal(kg->kg_proc, SIGSEGV);
+ PROC_LOCK(p);
+ psignal(p, SIGSEGV);
+ PROC_UNLOCK(p);
return (EFAULT);
}
- PROC_LOCK(kg->kg_proc);
+ PROC_LOCK(p);
if (mbx == (uintptr_t)kg->kg_completed) {
kg->kg_completed = td->td_mailbox;
- PROC_UNLOCK(kg->kg_proc);
+ PROC_UNLOCK(p);
break;
}
- PROC_UNLOCK(kg->kg_proc);
+ PROC_UNLOCK(p);
}
return (0);
}
@@ -385,6 +390,7 @@ thread_export_context(struct thread *td)
static int
thread_link_mboxes(struct ksegrp *kg, struct kse *ke)
{
+ struct proc *p = kg->kg_proc;
void *addr;
uintptr_t mbx;
@@ -397,17 +403,19 @@ thread_link_mboxes(struct ksegrp *kg, struct kse *ke)
for (;;) {
mbx = (uintptr_t)kg->kg_completed;
if (suword(addr, mbx)) {
- psignal(kg->kg_proc, SIGSEGV);
+ PROC_LOCK(p);
+ psignal(p, SIGSEGV);
+ PROC_UNLOCK(p);
return (EFAULT);
}
/* XXXKSE could use atomic CMPXCH here */
- PROC_LOCK(kg->kg_proc);
+ PROC_LOCK(p);
if (mbx == (uintptr_t)kg->kg_completed) {
kg->kg_completed = NULL;
- PROC_UNLOCK(kg->kg_proc);
+ PROC_UNLOCK(p);
break;
}
- PROC_UNLOCK(kg->kg_proc);
+ PROC_UNLOCK(p);
}
return (0);
}
OpenPOWER on IntegriCloud