Subject: NetBSD multi-threaded?
To: None <cgd@alpha.bostic.com>
From: Gordon W. Ross <gwr@jericho.mc.com>
List: tech-kern
Date: 09/13/1994 11:07:52
> Date: Mon, 12 Sep 1994 23:22:01 -0400
> From: "Chris G. Demetriou" <cgd@alpha.bostic.com>

> charles said:
> > In Net/2 and later, the struct user is now stored in a per-process
> > location, not a fixed location for all processes.
> 
> Actually...  In Net/2 and later, each process has its own 'struct
> user' location, but (at least as far as i'm aware) when a process is
> curproc, its user struct is doubly-mapped to a constant address as
> well.  That's definitely true of all the ports that i'm aware of (but
> then, i'm not familiar with the low-level details of them all).
> 
> The reason for this is rather interesting: when you fork, you've gotta
> copy the kernel stack.  the kernel stack typically lives at the 'high
> end' of the UPAGES, and the per-process struct user lives at the low
> end.  It's really a pain to have to re-thread the stack, so, by
> remapping the UPAGES at a fixed address for all processes, and only
> using the kernel stack in that mapping, a lot of hassle is avoided...

On a related note, I was looking into implementing a "guard page"
for the kernel stack, and realized I can not easily do it with the
current layout of UPAGES.  For a guard page, I would like to have
the kernel stack at the beginning of the UPAGES and the struct user
at the end (at least on a machine where stacks grow downward).
This way, kernel stack overflow touches an invalid page instead of
trashing the user struct.  Currently, fork "knows" this layout...

One scheme I've seen for declaring the UPAGES like I want is:

#include <sys/user.h>
/* This is a machine where the stack grows down. */
struct upages {
	char kstack[KERN_STACK_SIZE];
	struct user u;	/* traditional stuff from user.h */
};

The value of KERN_STACK_SIZE is computed such that struct upages
comes out to (UPAGES*NBPG) or a little less.

As a portability issue, struct upages should be defined in the
architecture-specific code to allow a weird, stack-grows-up-
machine to reverse teh order of the members of struct upages.
One could even add stuff, like the current struct pcb, or some
floating-point state, etc. to struct upages if desired.

Does anyone else care about guard pages?
Is there a better way to implement them?

Gordon