Code: Select all
IF segment register points to data or non-conforming code segment
Personally, I load %fs and %gs with null selectors, since they only "participate" in segmentation insofar as their base address is used, and that can be controlled either via wrfsbase or the appropriate MSR. Since the selector would not be pointing to a data or code descriptor, they do not get zeroed out. (I think -- I just tested this, and my fsbase value appears to stick across to the ring3 process)
Also, the processor doesn't zero out the base address, it simply writes a 0 to the selector. On Intel, this has the behaviour which you describe, in that the processor will also zero out the base address & limit (in the hidden part of the segment descriptor) when a NULL value is written to the selector. On AMD processors, the manual (in chapter 2, section 4.5.3) explicitly states:
When a null selector is loaded into FS or GS, the contents of the corresponding hidden descriptor register are not altered.
EDIT: I appear to have misread (and am mistaken) -- it does appear to be the case that while in Ring 0, FSBase becomes 0...
EDIT 2: this is not the case, I was doubly mistaken -- I had forgotten about some code I placed to zero out the segment selectors (including %fs) on a context switch -- naturally this clears the hidden base register (on QEMU at least, which appears to emulate the Intel behaviour). The stuff above should be correct, I think.