Skip site navigation (1)Skip section navigation (2)
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>