Re: 32-bit syscalls from 64-bit process on x86-64?
From: Andi Kleen
Date: Wed Dec 15 2004 - 23:37:28 EST
On Wed, Dec 15, 2004 at 12:58:05PM -0800, Jeremy Fitzhardinge wrote:
> On Wed, 2004-12-15 at 11:55 +0100, Andi Kleen wrote:
> > Hmm, in theory you could handle a 64bit signal frame from 32bit code
> > (just may need an assembly stub if you want the arguments). But it
> > would be quite ugly agreed.
>
> Yes. I've tried this out, and it works OK, but it isn't pleasing. One
> of the main problems is that the stack is likely to be above 4G, so %esp
> has no useful value, and when you switch to 64-bit mode, the top 32-bits
> of %rsp become undefined.
They seem to stay at the previous value in the current CPUs, but it's
undefined behaviour yes.
>
> > Perhaps it should force __USER_CS yes in this case, agreed.
> >
> > There is a small risk of breaking someone, but it's very small.
>
> Well, if they've got code which is already switching between 32 and 64
> bit segments, then they need to cope with either cs being current at
> delivery time.
Can you cope with that in valgrind? If I change it there will
be kernels with both behaviour around for a long time.
>
> > I can do that change if you want.
> >
> > BTW the long term plan is to get rid of the special cases to make
> > it easierto use the 32bit kernel ABI from a 64bit program.
> > This means signal handling will likely just check the code segment
> > at some point to decide if it should set up 32bit or 64bit frames
> > and we'll probably do similar things with the other cases
> > (except exec which needs to stay this way)
>
> At syscall time, rather than delivery time, I assume. Hm, I'd prefer it
> if it didn't look at the current segment, but at the syscall path. Ie,
> installing a handler with __NR_rt_sigaction via int 0x80 (or 32-bit
> syscall/sysenter) should set up a 32-bit frame on delivery, but if the
> handler was installed with the 64-bit syscall, it should be called with
> a 64-bit frame.
That would probably add some complications to the syscall exit path:
there is some code sharing between 32bit and 64bit, in particular 64bit
execve uses the IRET path to restore all registers and there can be a
signal after that.
The only case that wouldn't be handled by checking the segment would
be that if someone defines a 64bit LDT code segment and uses it, it
will not work. But that won't work anyways from 64bit because SYSRET
always forces __USER_CS. If you want to do any 64bit system calls
you cannot use such custom segment anyways.
So i don't see any drawbacks in just checking the segment for this.
-Andi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/