Subject: Re: Use of TSS
To: None <,>
From: Bruce Evans <>
List: port-i386
Date: 11/18/1993 19:54:48
>I'm considering whether it is worthwhile to use a TSS per process or
>not.  Currently, we allocate space for a TSS in each PCB.  My plan
>would be to use a single GDT slot and simply poke a new TSS descriptor
>in before we switch; that way we don't have an increasingly large GDT,

One statically allocated TSS is almost enough.  Minix-386 uses a single
TSS and pokes the kernel sp in before each switch; the kernel sp is the
only important thing in the TSS apart from the bitmap (unless h/w task
switching is used).  For 386BSD I think even this is unnecessary.  The
kernel sp is the same (virtual) address for all processes running in
user mode.

>The advantage here is that we could give fine-grain control of what
>I/O ports a process is allowed to use; i.e. a process which opens

I think I'd prefer trusting debugged applications with access to all
ports since going through the bitmap is slower.  Anyway, the bitmap
ought to be supported for use by non-debugged applications.

How about:
1. take TSS out of PCB.
2. single TSS in kernel for all processes not needing a bitmap.
3. on context switches, switch the TSS's iff the bitmap is different.
4. keep a few TSS's cached in the GDT.

How are you going to allocate large bitmaps?
malloc(sizeof(TSS) + bitmapsize) is easy but swapping the result
isn't.  A variable sized, swappable user area would be even harder.

>...  Also, the task
>switching code would be much simpler, as most of the work would be
>done by the processor.  The disadvantage is that it will probably be a
>little slower than the current task switching code.

Most of the above is independent of using h/w task switching.  I don't
think h/w task switching would be much simpler.  About the only thing it
would do more simply is switching cr3.  Hmmm ... swtch() is/should be:

	push call-saved-regs	// so natural it's hard to simplify
	discard call-used-regs	// h/w switch wastes time keeping them
	save old esp in old TSS	// h/w switch simpler
	// the current version actually saves all the regs in the TSS
	save npx if necessary	// not done by h/w switch
	save temp. map PTE	// not done by h/w switch
(Q1)	select new proc		// not done by h/w switch
(Q2)	update queues		// not done by h/w switch
	// someday switch TSS here if necessary
	switch cr3		// h/w switch simpler
	load new esp from TSS	// h/w switch simpler
	leave junk in call-used-regs	// h/w switch wastes time loading them
	pop call-saved-regs	// so natural it's hard to simplify
	// the current version actually loads all the regs from the TSS
	load temp. map PTE	// not done by h/w switch
(SS)	// h/w switch would also wasting switching a zillion segment
	// regs and the LDT

H/w task switching would be more attractive if it handled step Q2 and
maybe Q1, but taking advantage of that would require changing the
machine-independent parts of the kernel.  So would arranging for step
(SS) to do some good.  It's good for switching from a task outside
the kernel to another task outside the kernel but a waste of time for
switching between tasks already in the kernel.