PERFORCE change 55894 for review
David Xu
davidxu at FreeBSD.org
Sun Jun 27 04:23:27 GMT 2004
http://perforce.freebsd.org/chv.cgi?CH=55894
Change 55894 by davidxu at 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;
More information about the p4-projects
mailing list