Re: gpf in do_exit

Gabriel Paubert (paubert@iram.es)
Tue, 15 Sep 1998 16:50:03 +0200 (METDST)


On Mon, 14 Sep 1998, Linus Torvalds wrote:

>
>
> On Mon, 14 Sep 1998, Richard B. Johnson wrote:
> > >
> > > pushl %ss;\
> > > popl %ds;\
> > > pushl %ss;\
> > > popl %es;\
> > > pushl $11;\
> > > call do_exit
> > >
> > [SNIPPED]
> >
> > The segment registers are 16-bit registers!
>
> Yes. However, you should still use "pushl" and "popl", because they are
> smaller and faster. The upper bits are just ignored and/or push undefined
> values.
>
> Go figure, the x86 is a strange and wonderful beast.

However, the main reason to use 4 byte pushes and pops is to preserve
stack alignment. An interrupt handler executed on a misaligned stack would
have horrible performance.

>
> However, in this particular case the right thing to do is to just reset
> the segment register values in the trap handler rather than in entry.S.
> I'm doing that in my current kernel, I'll make a pre-2.1.122-3 shortly.
>

I did not want to speculate about this before seeing the code because
nobody should argue with God^H^H^HLinus without a good reason :-).

But I nevertheless think that you missed one case: with your patch, an
exception on popl %es in RESTORE_ALL will reset %ds to KERNEL_DS while at
this point in the code, %ds has its user mode value and it should
not be touched. The fixups in RESTORE_ALL are to my knowlege the only ones
which may be entered with user-mode %ds and/or %es (in a bugless kernel).
And the fixup on iret is very special in that it is the only one which
does not branch after a couple of machine instructions to an instructionn
close to the one that generated the exception.

BTW, modifying regs->xss in die_if_no_fixup is likely to thrash a local
variable in the routine generating the exception. %ss and %esp are not
saved when an exception occurs in kernel mode.

If you stick to resetting %ds and %es in die_if_no_fixup, I see only one
solution: it is to modify RESTORE_ALL to do something like:

1: mov (%esp),%ds
2: mov 4(%esp),%es
addl $12,%esp
3: iret
.section fixup,"ax"
4: movl $0,(%esp)
jmp 1b
5: movl $0,4(%esp)
jmp 1b
6: pushl $11
call do_exit
.previous
.section __ex_table,"a"
.long 1b,4b
.long 2b,5b
.long 3b,6b

which I find quite ugly.

Gabriel.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/