Date: Wed, 24 Jan 2007 14:36:36 +0100 From: Tijl Coosemans <tijl@ulyssis.org> To: freebsd-emulation@freebsd.org Cc: peter@freebsd.org, jkim@freebsd.org Subject: Re: linuxolator: tls_test results amd64 Message-ID: <200701241436.40627.tijl@ulyssis.org> In-Reply-To: <200701231910.02033.jkim@FreeBSD.org> References: <790a9fff0701211041j1176d00gd6dd75d0989cf4ec@mail.gmail.com> <200701231812.48455.jkim@FreeBSD.org> <200701231910.02033.jkim@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday 24 January 2007 01:09, Jung-uk Kim wrote: > On Tuesday 23 January 2007 06:12 pm, Jung-uk Kim wrote: > > On Tuesday 23 January 2007 05:59 pm, Tijl Coosemans wrote: > > > On Tuesday 23 January 2007 23:43, Tijl Coosemans wrote: > > > > On Tuesday 23 January 2007 21:55, Jung-uk Kim wrote: > > > > > On Tuesday 23 January 2007 03:13 pm, Tijl Coosemans wrote: > > > > > > On Tuesday 23 January 2007 20:00, Jung-uk Kim wrote: > > > > > > > Second problem is MSR_KGSBASE is scrubbed by something > > > > > > > during context switch, i.e., it becomes 0 some times. > > > > > > > > > > Saved pcb_gsbase seems always correct. MSR_KGSBASE is not, > > > > > which is supposedly swapped with MSR_GSBASE via swapgs. > > > > > Maybe I am confused, or maybe my CPU is too old (it's C0 > > > > > stepping and I know there are some segmentation issues with > > > > > the revision) but that's what I see. I need more time for > > > > > testing (or resting?). > > > > > > > > Ok, I understand why pcb_gsbase is always correct. It is never > > > > written to except for cpu_set_user_tls, i386_set_gsbase and > > > > set_thread_area. cpu_switch only reads from it to restore > > > > gsbase. At least, that's what cpu_switch does in case of 64 bit > > > > programs, not 32 bit it seems. Why is that? Why is there a jmp > > > > on line 186 in sys/amd64/amd64/cpu_switch.S? > > > > > > This doesn't explain why gsbase becomes 0 by the way. I still > > > think that's because glibc does "mov index,%gs" after calling > > > set_thread_area. > > > > That's correct. See: > > > > http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/linuxthreads/linuxthreads/sysdeps/i386/tls.h?rev=1.39&content-type=text/plain&cvsroot=glibc > > I have read through entire segment register section of AMD64 manual > and I understand the whole picture now. fsbase/gsbase is not > restored for 32-bit thread because it is ignored in Compatibility > Mode. In Compatibility Mode, the segment regiter load is exactly > like legacy x86 mode, i.e., hidden portion is not loaded from > fsbase/gsbase but from GDT. So, you're right; there is no other way > to implement this correctly without setting up segment > descriptor. :-( That's not how I understood the manual. I think in the case of FS and GS, segment register load is the same in both modes (32/64). That is, in both cases the 32 bit base address in the GDT descriptor is copied to the lower 32 bits of the base address in the hidden portion of the segment register and the upper 32 bits of this address are set to 0. If you want to set the full 64 bit base address, you have to use wrmsr. The only difference between 64 bit mode and 32 bit compatibility mode in this case is that in compat mode, the upper 32 bit of this base address are ignored for address calculations. So I don't think pcb_fsbase and pcb_gsbase should be ignored when switching to a 32 bit thread as they are now. How else are i386_set_fsbase/gsbase supposed to work?
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701241436.40627.tijl>