Skip site navigation (1)Skip section navigation (2)
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>