PERFORCE change 43105 for review

Marcel Moolenaar marcel at FreeBSD.org
Thu Nov 27 15:36:18 PST 2003


http://perforce.freebsd.org/chv.cgi?CH=43105

Change 43105 by marcel at marcel_nfs on 2003/11/27 15:36:00

	Simplify the mcontext handling. Any synchronous context created
	by the kernel is the same now. Add _MC_FLAGS_SYSCALL_CONTEXT to
	mark a synchronous kernel context as such.
	Remove _MC_FLAGS_SCRATCH_VALID & _MC_FLAGS_RETURN_VALID.
	Move the handling of _MC_FLAGS_KSE_SET_MBOX out of set_mcontext()
	and into trap() where it's important. The flag is going away, so
	this change clusters the obsolete code.
	
	Note that this change does not try to preserve the ABI beyond
	making sure one can do a source upgrade without being hosed.

Affected files ...

.. //depot/projects/ia64/sys/ia64/ia64/machdep.c#100 edit
.. //depot/projects/ia64/sys/ia64/ia64/trap.c#67 edit
.. //depot/projects/ia64/sys/ia64/include/ucontext.h#6 edit

Differences ...

==== //depot/projects/ia64/sys/ia64/ia64/machdep.c#100 (text+ko) ====

@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2003 Marcel Moolenaar
  * Copyright (c) 2000,2001 Doug Rabson
  * All rights reserved.
  *
@@ -918,7 +919,7 @@
 	mtx_unlock(&psp->ps_mtx);
 	PROC_UNLOCK(p);
 
-	get_mcontext(td, &sf.sf_uc.uc_mcontext, GET_MC_IA64_SCRATCH);
+	get_mcontext(td, &sf.sf_uc.uc_mcontext);
 
 	/* Copy the frame out to userland. */
 	if (copyout(&sf, sfp, sizeof(sf)) != 0) {
@@ -1070,24 +1071,13 @@
 	} else
 		mc->mc_special = tf->tf_special;
 	if (tf->tf_flags & FRAME_SYSCALL) {
-		if (flags & GET_MC_IA64_SCRATCH) {
-			mc->mc_flags |= _MC_FLAGS_SCRATCH_VALID;
-			mc->mc_scratch = tf->tf_scratch;
-		} else {
-			/*
-			 * Put the syscall return values in the context.  We
-			 * need this for swapcontext() to work.  Note that we
-			 * don't use gr11 in the kernel, but the runtime
-			 * specification defines it as a return register,
-			 * just like gr8-gr10.
-			 */
-			mc->mc_flags |= _MC_FLAGS_RETURN_VALID;
-			if ((flags & GET_MC_CLEAR_RET) == 0) {
-				mc->mc_scratch.gr8 = tf->tf_scratch.gr8;
-				mc->mc_scratch.gr9 = tf->tf_scratch.gr9;
-				mc->mc_scratch.gr10 = tf->tf_scratch.gr10;
-				mc->mc_scratch.gr11 = tf->tf_scratch.gr11;
-			}
+		mc->mc_flags |= _MC_FLAGS_SYSCALL_CONTEXT;
+		mc->mc_scratch = tf->tf_scratch;
+		if (flags & GET_MC_CLEAR_RET) {
+			mc->mc_scratch.gr8 = 0;
+			mc->mc_scratch.gr9 = 0;
+			mc->mc_scratch.gr10 = 0;
+			mc->mc_scratch.gr11 = 0;
 		}
 	} else {
 		mc->mc_flags |= _MC_FLAGS_ASYNC_CONTEXT;
@@ -1137,33 +1127,24 @@
 		 * the syscall is sigreturn(2).
 		 */
 		if (tf->tf_flags & FRAME_SYSCALL)
-			KASSERT(tf->tf_scratch.gr15 == SYS_sigreturn, ("foo"));
+			KASSERT(tf->tf_scratch.gr15 == SYS_sigreturn ||
+			    tf->tf_scratch.gr15 == SYS_kse_switchin, ("foo"));
 		tf->tf_scratch = mc->mc_scratch;
 		tf->tf_scratch_fp = mc->mc_scratch_fp;
 		if (mc->mc_flags & _MC_FLAGS_HIGHFP_VALID)
 			td->td_pcb->pcb_high_fp = mc->mc_high_fp;
 	} else {
 		KASSERT((tf->tf_flags & FRAME_SYSCALL) != 0, ("foo"));
-		if ((mc->mc_flags & _MC_FLAGS_SCRATCH_VALID) == 0) {
+		if ((mc->mc_flags & _MC_FLAGS_SYSCALL_CONTEXT) == 0) {
 			s.cfm = tf->tf_special.cfm;
 			s.iip = tf->tf_special.iip;
 			tf->tf_scratch.gr15 = 0;	/* Clear syscall nr. */
-			if (mc->mc_flags & _MC_FLAGS_RETURN_VALID) {
-				tf->tf_scratch.gr8 = mc->mc_scratch.gr8;
-				tf->tf_scratch.gr9 = mc->mc_scratch.gr9;
-				tf->tf_scratch.gr10 = mc->mc_scratch.gr10;
-				tf->tf_scratch.gr11 = mc->mc_scratch.gr11;
-			}
 		} else
 			tf->tf_scratch = mc->mc_scratch;
 	}
 	tf->tf_special = s;
 	restore_callee_saved(&mc->mc_preserved);
 	restore_callee_saved_fp(&mc->mc_preserved_fp);
-
-	if (mc->mc_flags & _MC_FLAGS_KSE_SET_MBOX)
-		suword((caddr_t)mc->mc_special.ifa, mc->mc_special.isr);
-
 	return (0);
 }
 

==== //depot/projects/ia64/sys/ia64/ia64/trap.c#67 (text+ko) ====

@@ -452,6 +452,11 @@
 				    &mc, sizeof(mc));
 				if (!error) {
 					set_mcontext(td, &mc);
+					if (mc.mc_flags &
+					    _MC_FLAGS_KSE_SET_MBOX)
+						suword((caddr_t)
+						    mc.mc_special.ifa,
+						    mc.mc_special.isr);
 					return;	/* Don't call do_ast()!!! */
 				}
 				ucode = framep->tf_scratch.gr8;

==== //depot/projects/ia64/sys/ia64/include/ucontext.h#6 (text+ko) ====

@@ -45,48 +45,42 @@
  * call to the function that creates the context. An asynctx needs to have the
  * scratch registers preserved because it can describe any point in a thread's
  * (or process') execution.
+ * The second variation is for synchronous contexts. When the kernel creates
+ * a synchronous context if needs to preserve the scratch registers, because
+ * the syscall argument and return values are stored there in the trapframe
+ * and they need to be preserved in other to restart a syscall or return the
+ * proper return values. Also, the IIP and CFM fields need to be preserved
+ * as they point to the syscall stub, which the kernel saves as a favor to
+ * userland (it keeps the stubs small and simple).
  *
  * Below a description of the flags and their meaning:
  *
  *	_MC_FLAGS_ASYNC_CONTEXT
  *		If set, indicates that mc_scratch and mc_scratch_fp are both
- *		valid. IFF not set, _MC_FLAGS_RETURN_VALID indicates if the
- *		return registers are valid or not.
+ *		valid. IFF not set, _MC_FLAGS_SYSCALL_CONTEXT indicates if the
+ *		synchronous context is one corresponding to a syscall or not.
+ *		Only the kernel is expected to create such a context and it's
+ *		probably wise to let the kernel restore it.
  *	_MC_FLAGS_HIGHFP_VALID
  *		If set, indicates that the high FP registers (f32-f127) are
  *		valid. This flag is very likely not going to be set for any
  *		sensible synctx, but is not explicitly disallowed. Any synctx
  *		that has this flag may or may not have the high FP registers
  *		restored. In short: don't do it.
- *	_MC_FLAGS_KSE_SET_MBOX
- *		This flag is special to setcontext(2) and swapcontext(2). It
- *		instructs the kernel to write the value in mc_special.isr to
- *		the memory address pointed to by mc_special.ifa. This allows
- *		the kernel to switch to a new context in a KSE based threaded
- *		program. Note that this is a non-srandard extension to the
- *		otherwise standard system calls and use of this flag should be
- *		limited to KSE.
- *	_MC_FLAGS_RETURN_VALID
- *		If set and _MC_FLAGS_ASYNC_CONTEXT is not set indicates that
- *		the ABI defined return registers are valid. Both getcontext(2)
- *		and swapcontext(2) need to save the system call return values.
- *		Any synctx that does not have this flag may still have the
- *		return registers restored from the context.
- *	_MC_FLAGS_SCRATCH_VALID
- *		If set and _MC_FLAGS_ASYNC_CONTEXT is not set indicates that
- *		the scratch registers, but not the FP registers are valid.
- *		This flag is set in contexts passed to signal handlers. This
- *		flag is a superset of _MC_FLAGS_RETURN_VALID. If both flags
- *		are set, this flag takes precedence.
+ *	_MC_FLAGS_SYSCALL_CONTEXT
+ *		If set (hence _MC_FLAGS_ASYNC_CONTEXT is not set) indicates
+ *		that the scratch registers contain syscall arguments and
+ *		return values and that additionally IIP and CFM are valid.
+ *		Only the kernel is expected to create such a context. It's
+ *		probably wise to let the kernel restore it.
  */
 
 typedef struct __mcontext {
 	unsigned long		mc_flags;
 #define	_MC_FLAGS_ASYNC_CONTEXT		0x0001
 #define	_MC_FLAGS_HIGHFP_VALID		0x0002
-#define	_MC_FLAGS_KSE_SET_MBOX		0x0004
-#define	_MC_FLAGS_RETURN_VALID		0x0008
-#define	_MC_FLAGS_SCRATCH_VALID		0x0010
+#define	_MC_FLAGS_KSE_SET_MBOX		0x0004	/* undocumented. Has to go. */
+#define	_MC_FLAGS_SYSCALL_CONTEXT	0x0008
 	unsigned long		_reserved_;
 	struct _special		mc_special;
 	struct _callee_saved	mc_preserved;
@@ -96,9 +90,4 @@
 	struct _high_fp		mc_high_fp;
 } mcontext_t;
 
-#ifdef _KERNEL
-/* Flags for get_mcontext().  See also <sys/ucontext.h>. */
-#define	GET_MC_IA64_SCRATCH	0x10
-#endif
-
 #endif /* !_MACHINE_UCONTEXT_H_ */


More information about the p4-projects mailing list