> In i386/i386/trap.c if %gs is invalid... for example, a process with a
> USER_LDT takes an interrupt while exiting, or if %gs is set
> through procfs,
> the fault check must occur regardless of the interrupt nesting
> level because
> mainline code does not push and load a %gs for the kernel.
>
I don't quite get it. There'll be fault only when the kernel tries to
load an invalid %gs. And there's only one place that the kernel would
load a new %gs: during a context switch, which could not take place in
an interrupt context.
> FreeBSD-5.x has already moved this check to outside the nesting
> level test.
>
> It may also be possible that %fs can cause the same problem to occur in
> the situation with a process takes an interrupt while exiting and %fs is
> set to a USER_LDT entry. I have not checked this, but if it is
> true it would
> be a problem in both -current and -stable for the exiting case.
>
It's different for %fs, it holds a valid kernel segment at all time
inside the kernel.
>
> if (intr_nesting_level == 0) {
> /*
> * Invalid %fs's and %gs's can be created using
> * procfs or PT_SETREGS or by invalidating the
> * underlying LDT entry. This causes a fault
> * in kernel mode when the kernel attempts to
> * switch contexts. Lose the bad context
> * (XXX) so that we can continue, and generate
> * a signal.
> */
> if (frame.tf_eip == (int)cpu_switch_load_gs) { <<< WRONG
> curpcb->pcb_gs = 0; <<<
> psignal(p, SIGBUS); <<<
> return; <<<
> }
> MAYBE_DORETI_FAULT(doreti_iret,
> doreti_iret_fault);
>
>
-lq