RE: [PATCH] x86/ia32: Do not modify the DPL bits for a null selector

From: Li, Xin3
Date: Thu Jul 06 2023 - 22:29:44 EST


> > When a null selector is to be loaded into a segment register,
> > reload_segments() sets its DPL bits to 3. Later when an IRET
> > instruction loads it, it zeros the segment register. The two
> > operations offset each other to actually effect a nop.
> >
> > Fix it by not modifying the DPL bits for a null selector.
>
> So in the end, this is an optimization attempt? Is there any other benefit?

You asked but I think you have the answer 😉, but want me to give the
details in the commit message, which probably I should have done.

Unlike IRET, ERETU, introduced with FRED to return to ring 3 from ring
0, does not make any of DS, ES, FS, or GS null if it is found to have
DPL < 3. It is expected that a FRED-enabled operating system will return
to ring 3 (in compatibility mode) only when those non-null selectors
all have DPL = 3.

Thus when FRED is enabled, because reload_segments() sets the DPL bits
of null selector to 3, we end up with having 3 in a segment register
even when it is initially set to 0. As a result, the sigreturn selftest
fails as it sets DS to 0 and then checks if it's still 0 after sigreturn.

Thanks!
Xin