From 1434d3fe6fbdf2e79767e8a4eb7ea58247327395 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Thu, 24 Oct 2002 23:09:48 +0000 Subject: [PATCH] Extract out KSE specific code from machine specific code so that there is ony one copy of it. Fix that one copy so that KSEs with no mailbox in a KSE program are not a cause of page faults (this can legitmatly happen). Submitted by: (parts) davidxu --- sys/alpha/alpha/trap.c | 20 ++-------------- sys/amd64/amd64/trap.c | 40 ++------------------------------ sys/i386/i386/trap.c | 40 ++------------------------------ sys/ia64/ia64/trap.c | 20 ++-------------- sys/kern/kern_kse.c | 47 ++++++++++++++++++++++++++++++++++++++ sys/kern/kern_thread.c | 47 ++++++++++++++++++++++++++++++++++++++ sys/sparc64/sparc64/trap.c | 19 ++------------- sys/sys/proc.h | 1 + 8 files changed, 105 insertions(+), 129 deletions(-) diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c index 3db80deeeef7..6c554f75c30e 100644 --- a/sys/alpha/alpha/trap.c +++ b/sys/alpha/alpha/trap.c @@ -669,24 +669,8 @@ syscall(code, framep) sticks = td->td_kse->ke_sticks; if (td->td_ucred != p->p_ucred) cred_update_thread(td); - if (p->p_flag & P_KSES) { - /* - * If we are doing a syscall in a KSE environment, - * note where our mailbox is. There is always the - * possibility that we could do this lazily (in sleep()), - * but for now do it every time. - */ - td->td_mailbox = (void *)fuword((caddr_t)td->td_kse->ke_mailbox - + offsetof(struct kse_mailbox, km_curthread)); - if ((td->td_mailbox == NULL) || - (td->td_mailbox == (void *)-1)) { - td->td_mailbox = NULL; /* single thread it.. */ - td->td_flags &= ~TDF_UNBOUND; - } else { - td->td_flags |= TDF_UNBOUND; - } - } - + if (p->p_flag & P_KSES) + thread_user_enter(p, td); #ifdef DIAGNOSTIC alpha_fpstate_check(td); #endif diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index fdc0b49d776b..a23ce493a3b2 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -963,44 +963,8 @@ syscall(frame) td->td_frame = &frame; if (td->td_ucred != p->p_ucred) cred_update_thread(td); - if (p->p_flag & P_KSES) { - /* - * First check that we shouldn't just abort. - * But check if we are the single thread first! - * XXX p_singlethread not locked, but should be safe. - */ - if ((p->p_flag & P_WEXIT) && (p->p_singlethread != td)) { - PROC_LOCK(p); - mtx_lock_spin(&sched_lock); - thread_exit(); - /* NOTREACHED */ - } - - /* - * If we are doing a syscall in a KSE environment, - * note where our mailbox is. There is always the - * possibility that we could do this lazily (in sleep()), - * but for now do it every time. - */ -#if 0 - td->td_mailbox = (void *)fuword((caddr_t)td->td_kse->ke_mailbox - + offsetof(struct kse_mailbox, km_curthread)); -#else /* if user pointer arithmetic is ok in the kernel */ - td->td_mailbox = - (void *)fuword( - (void *)&td->td_kse->ke_mailbox->km_curthread); -#endif - if ((td->td_mailbox == NULL) || - (td->td_mailbox == (void *)-1)) { - td->td_mailbox = NULL; /* single thread it.. */ - td->td_flags &= ~TDF_UNBOUND; - } else { - if (td->td_standin == NULL) { - td->td_standin = thread_alloc(); - } - td->td_flags |= TDF_UNBOUND; - } - } + if (p->p_flag & P_KSES) + thread_user_enter(p, td); params = (caddr_t)frame.tf_esp + sizeof(int); code = frame.tf_eax; orig_tf_eflags = frame.tf_eflags; diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index fdc0b49d776b..a23ce493a3b2 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -963,44 +963,8 @@ syscall(frame) td->td_frame = &frame; if (td->td_ucred != p->p_ucred) cred_update_thread(td); - if (p->p_flag & P_KSES) { - /* - * First check that we shouldn't just abort. - * But check if we are the single thread first! - * XXX p_singlethread not locked, but should be safe. - */ - if ((p->p_flag & P_WEXIT) && (p->p_singlethread != td)) { - PROC_LOCK(p); - mtx_lock_spin(&sched_lock); - thread_exit(); - /* NOTREACHED */ - } - - /* - * If we are doing a syscall in a KSE environment, - * note where our mailbox is. There is always the - * possibility that we could do this lazily (in sleep()), - * but for now do it every time. - */ -#if 0 - td->td_mailbox = (void *)fuword((caddr_t)td->td_kse->ke_mailbox - + offsetof(struct kse_mailbox, km_curthread)); -#else /* if user pointer arithmetic is ok in the kernel */ - td->td_mailbox = - (void *)fuword( - (void *)&td->td_kse->ke_mailbox->km_curthread); -#endif - if ((td->td_mailbox == NULL) || - (td->td_mailbox == (void *)-1)) { - td->td_mailbox = NULL; /* single thread it.. */ - td->td_flags &= ~TDF_UNBOUND; - } else { - if (td->td_standin == NULL) { - td->td_standin = thread_alloc(); - } - td->td_flags |= TDF_UNBOUND; - } - } + if (p->p_flag & P_KSES) + thread_user_enter(p, td); params = (caddr_t)frame.tf_esp + sizeof(int); code = frame.tf_eax; orig_tf_eflags = frame.tf_eflags; diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c index 2dc40b19ec20..d0e4aa616458 100644 --- a/sys/ia64/ia64/trap.c +++ b/sys/ia64/ia64/trap.c @@ -808,24 +808,8 @@ syscall(int code, u_int64_t *args, struct trapframe *framep) framep->tf_cr_iip += 16; } - if (p->p_flag & P_KSES) { - /* - * If we are doing a syscall in a KSE environment, - * note where our mailbox is. There is always the - * possibility that we could do this lazily (in sleep()), - * but for now do it every time. - */ - td->td_mailbox = (void *)fuword((caddr_t)td->td_kse->ke_mailbox - + offsetof(struct kse_mailbox, km_curthread)); - if ((td->td_mailbox == NULL) || - (td->td_mailbox == (void *)-1)) { - td->td_mailbox = NULL; /* single thread it.. */ - td->td_flags &= ~TDF_UNBOUND; - } else { - td->td_flags |= TDF_UNBOUND; - } - } - + if (p->p_flag & P_KSES) + thread_user_enter(p, td); #ifdef DIAGNOSTIC ia64_fpstate_check(td); #endif diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index 02a62f6ee587..d47f32e908e2 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -1157,6 +1157,53 @@ return (NULL); return (td2); } +/* + * setup done on the thread when it enters the kernel. + * XXXKSE Presently only for syscalls but eventually all kernel entries. + */ +void +thread_user_enter(struct proc *p, struct thread *td) +{ + struct kse *ke; + + /* + * First check that we shouldn't just abort. + * But check if we are the single thread first! + * XXX p_singlethread not locked, but should be safe. + */ + if ((p->p_flag & P_WEXIT) && (p->p_singlethread != td)) { + PROC_LOCK(p); + mtx_lock_spin(&sched_lock); + thread_exit(); + /* NOTREACHED */ + } + + /* + * If we are doing a syscall in a KSE environment, + * note where our mailbox is. There is always the + * possibility that we could do this lazily (in sleep()), + * but for now do it every time. + */ + if ((ke = td->td_kse->ke_mailbox)) { +#if 0 + td->td_mailbox = (void *)fuword((caddr_t)ke->ke_mailbox + + offsetof(struct kse_mailbox, km_curthread)); +#else /* if user pointer arithmetic is ok in the kernel */ + td->td_mailbox = + (void *)fuword( (void *)&ke->ke_mailbox->km_curthread); +#endif + if ((td->td_mailbox == NULL) || + (td->td_mailbox == (void *)-1)) { + td->td_mailbox = NULL; /* single thread it.. */ + td->td_flags &= ~TDF_UNBOUND; + } else { + if (td->td_standin == NULL) + td->td_standin = thread_alloc(); + td->td_flags |= TDF_UNBOUND; + } + } +} + /* * The extra work we go through if we are a threaded process when we * return to userland. diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 02a62f6ee587..d47f32e908e2 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -1157,6 +1157,53 @@ return (NULL); return (td2); } +/* + * setup done on the thread when it enters the kernel. + * XXXKSE Presently only for syscalls but eventually all kernel entries. + */ +void +thread_user_enter(struct proc *p, struct thread *td) +{ + struct kse *ke; + + /* + * First check that we shouldn't just abort. + * But check if we are the single thread first! + * XXX p_singlethread not locked, but should be safe. + */ + if ((p->p_flag & P_WEXIT) && (p->p_singlethread != td)) { + PROC_LOCK(p); + mtx_lock_spin(&sched_lock); + thread_exit(); + /* NOTREACHED */ + } + + /* + * If we are doing a syscall in a KSE environment, + * note where our mailbox is. There is always the + * possibility that we could do this lazily (in sleep()), + * but for now do it every time. + */ + if ((ke = td->td_kse->ke_mailbox)) { +#if 0 + td->td_mailbox = (void *)fuword((caddr_t)ke->ke_mailbox + + offsetof(struct kse_mailbox, km_curthread)); +#else /* if user pointer arithmetic is ok in the kernel */ + td->td_mailbox = + (void *)fuword( (void *)&ke->ke_mailbox->km_curthread); +#endif + if ((td->td_mailbox == NULL) || + (td->td_mailbox == (void *)-1)) { + td->td_mailbox = NULL; /* single thread it.. */ + td->td_flags &= ~TDF_UNBOUND; + } else { + if (td->td_standin == NULL) + td->td_standin = thread_alloc(); + td->td_flags |= TDF_UNBOUND; + } + } +} + /* * The extra work we go through if we are a threaded process when we * return to userland. diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index 38ca30f21fb9..ded23a45c829 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -575,23 +575,8 @@ syscall(struct trapframe *tf) td->td_frame = tf; if (td->td_ucred != p->p_ucred) cred_update_thread(td); - if (p->p_flag & P_KSES) { - /* - * If we are doing a syscall in a KSE environment, - * note where our mailbox is. There is always the - * possibility that we could do this lazily (in sleep()), - * but for now do it every time. - */ - td->td_mailbox = (void *)fuword((caddr_t)td->td_kse->ke_mailbox - + offsetof(struct kse_mailbox, km_curthread)); - if ((td->td_mailbox == NULL) || - (td->td_mailbox == (void *)-1)) { - td->td_mailbox = NULL; /* single thread it.. */ - td->td_flags &= ~TDF_UNBOUND; - } else { - td->td_flags |= TDF_UNBOUND; - } - } + if (p->p_flag & P_KSES) + thread_user_enter(p, td); code = tf->tf_global[1]; /* diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 0ef375681273..1e267d7648e8 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -931,6 +931,7 @@ void thread_suspend_one(struct thread *td); void thread_unsuspend(struct proc *p); void thread_unsuspend_one(struct thread *td); int thread_userret(struct thread *td, struct trapframe *frame); +void thread_user_enter(struct proc *p, struct thread *td); void thread_sanity_check(struct thread *td, char *); #endif /* _KERNEL */