Date: Sun, 27 Jun 2004 04:23:14 GMT From: David Xu <davidxu@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 55894 for review Message-ID: <200406270423.i5R4NEnU088498@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=55894 Change 55894 by davidxu@davidxu_alona on 2004/06/27 04:22:54 Adjust kse_switchin code to accept mailbox pointer. Add code to export lwpid to mailbox, so debugger can map kernel lwp to user thread. Affected files ... .. //depot/projects/davidxu_ksedbg/src/sys/kern/kern_kse.c#2 edit Differences ... ==== //depot/projects/davidxu_ksedbg/src/sys/kern/kern_kse.c#2 (text+ko) ==== @@ -35,6 +35,7 @@ #include <sys/lock.h> #include <sys/mutex.h> #include <sys/proc.h> +#include <sys/ptrace.h> #include <sys/smp.h> #include <sys/sysproto.h> #include <sys/sched.h> @@ -123,28 +124,45 @@ } } - #ifndef _SYS_SYSPROTO_H_ struct kse_switchin_args { - const struct __mcontext *mcp; - long val; - long *loc; + struct kse_thr_mailbox *tmbx; + int flags; }; #endif int kse_switchin(struct thread *td, struct kse_switchin_args *uap) { - mcontext_t mc; + struct kse_thr_mailbox tmbx; + struct kse_upcall *ku; int error; - error = (uap->mcp == NULL) ? EINVAL : 0; + if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td)) + return (EINVAL); + error = (uap->tmbx == NULL) ? EINVAL : 0; if (!error) - error = copyin(uap->mcp, &mc, sizeof(mc)); - if (!error && uap->loc != NULL) - error = (suword(uap->loc, uap->val) != 0) ? EINVAL : 0; + error = copyin(uap->tmbx, &tmbx, sizeof(tmbx)); + if (!error && (uap->flags & KSE_SWITCHIN_SETTMBX)) + error = (suword(&ku->ku_mailbox->km_curthread, + (long)uap->tmbx) != 0 ? EINVAL : 0); if (!error) - error = set_mcontext(td, &mc); + error = set_mcontext(td, &tmbx.tm_context.uc_mcontext); + if (!error) { + suword32(&uap->tmbx->tm_lwp, td->td_tid); + if (uap->flags & KSE_SWITCHIN_SETTMBX) { + td->td_mailbox = uap->tmbx; + mtx_lock_spin(&sched_lock); + td->td_flags |= TDF_CAN_UNBIND; + mtx_unlock_spin(&sched_lock); + } + if (td->td_proc->p_flag & P_TRACED) { + if (tmbx.tm_dflags & TMDF_SSTEP) + ptrace_single_step(td); + else + ptrace_clear_single_step(td); + } + } return ((error == 0) ? EJUSTRETURN : error); } @@ -271,7 +289,7 @@ * If that fails then just go for a segfault. * XXX need to check it that can be deliverred without a mailbox. */ - error = suword(&ku->ku_mailbox->km_flags, ku->ku_mflags|KMF_DONE); + error = suword32(&ku->ku_mailbox->km_flags, ku->ku_mflags|KMF_DONE); PROC_LOCK(p); if (error) psignal(p, SIGSEGV); @@ -327,7 +345,7 @@ if (td->td_pflags & TDP_SA) td->td_pflags |= TDP_UPCALLING; else { - ku->ku_mflags = fuword(&ku->ku_mailbox->km_flags); + ku->ku_mflags = fuword32(&ku->ku_mailbox->km_flags); if (ku->ku_mflags == -1) { PROC_LOCK(p); sigexit(td, SIGSEGV); @@ -459,8 +477,12 @@ ncpus = virtual_cpu; if (!(mbx.km_flags & KMF_BOUND)) sa = TDP_SA; - else + else { + if (mbx.km_curthread == NULL) + return (EINVAL); ncpus = 1; + } + PROC_LOCK(p); if (!(p->p_flag & P_SA)) { first = 1; @@ -599,20 +621,26 @@ newtd = thread_schedule_upcall(td, newku); } } + mtx_unlock_spin(&sched_lock); + suword32(&newku->ku_mailbox->km_lwp, newtd->td_tid); + if (mbx.km_curthread) + suword32(&mbx.km_curthread->tm_lwp, newtd->td_tid); if (!sa) { newtd->td_mailbox = mbx.km_curthread; newtd->td_pflags &= ~TDP_SA; if (newtd != td) { - mtx_unlock_spin(&sched_lock); cpu_set_upcall_kse(newtd, newku); - mtx_lock_spin(&sched_lock); + if (p->p_flag & P_TRACED) + ptrace_clear_single_step(newtd); } } else { newtd->td_pflags |= TDP_SA; } - if (newtd != td) + if (newtd != td) { + mtx_lock_spin(&sched_lock); setrunqueue(newtd); - mtx_unlock_spin(&sched_lock); + mtx_unlock_spin(&sched_lock); + } return (0); } @@ -683,21 +711,6 @@ p = td->td_proc; kg = td->td_ksegrp; - /* Export the user/machine context. */ - get_mcontext(td, &mc, 0); - addr = (void *)(&td->td_mailbox->tm_context.uc_mcontext); - error = copyout(&mc, addr, sizeof(mcontext_t)); - if (error) - goto bad; - - /* Exports clock ticks in kernel mode */ - addr = (caddr_t)(&td->td_mailbox->tm_sticks); - temp = fuword32(addr) + td->td_usticks; - if (suword32(addr, temp)) { - error = EFAULT; - goto bad; - } - /* * Post sync signal, or process SIGKILL and SIGSTOP. * For sync signal, it is only possible when the signal is not @@ -717,6 +730,27 @@ SIGFILLSET(td->td_sigmask); PROC_UNLOCK(p); + /* Export the user/machine context. */ + get_mcontext(td, &mc, 0); + addr = (void *)(&td->td_mailbox->tm_context.uc_mcontext); + error = copyout(&mc, addr, sizeof(mcontext_t)); + if (error) + goto bad; + + /* Exports clock ticks in kernel mode */ + addr = (caddr_t)(&td->td_mailbox->tm_sticks); + temp = fuword32(addr) + td->td_usticks; + if (suword32(addr, temp)) { + error = EFAULT; + goto bad; + } + + addr = (caddr_t)(&td->td_mailbox->tm_lwp); + if (suword32(addr, 0)) { + error = EFAULT; + goto bad; + } + /* Get address in latest mbox of list pointer */ addr = (void *)(&td->td_mailbox->tm_next); /* @@ -944,14 +978,14 @@ cpu_thread_siginfo(sig, 0, &siginfo); mtx_unlock(&ps->ps_mtx); + SIGADDSET(td->td_sigmask, sig); PROC_UNLOCK(p); error = copyout(&siginfo, &td->td_mailbox->tm_syncsig, sizeof(siginfo)); if (error) { PROC_LOCK(p); - sigexit(td, SIGILL); + sigexit(td, SIGSEGV); } PROC_LOCK(p); - SIGADDSET(td->td_sigmask, sig); mtx_lock(&ps->ps_mtx); } @@ -991,7 +1025,6 @@ /* * 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) @@ -1203,6 +1236,12 @@ */ if (!(ku->ku_mflags & KMF_NOUPCALL)) { cpu_set_upcall_kse(td, ku); + if (p->p_flag & P_TRACED) + ptrace_clear_single_step(td); + error = suword32(&ku->ku_mailbox->km_lwp, + td->td_tid); + if (error) + goto out; error = suword(&ku->ku_mailbox->km_curthread, 0); if (error) goto out;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406270423.i5R4NEnU088498>