Brandon Pickering
Brandon Pickering

Reputation: 315

Why have two overlapping data segments (e.g. in the Linux kernel)?

In the Linux kernel, as well as in many x86 tutorials online, I see that people recommend using two code segments and two data segments. I understand the need for two code segments, as the CPL needs to exactly match the DPL (for non-conforming segments).

However, none of these tutorials (nor any of the related questions on StackOverflow), specifically say why we need two data segments. These work differently than code segments, since a process with CPL=0 can access a data segment with DPL=3.

The downside to having two data segments is having to reload the DS, ES, etc. registers if we have switching between processes of different privilege levels.

So my specific question is: given that we are using a flat memory model, so that all code and segments entirely overlap, what purpose does it serve to have a user and a kernel data segment, as opposed to just one user data segment?

Upvotes: 2

Views: 535

Answers (1)

Margaret Bloom
Margaret Bloom

Reputation: 44066

There is an explanation here.

Quoting from Intel manuals (Section 5.7)

Privilege level checking also occurs when the SS register is loaded with the segment selector for a stack segment.
Here all privilege levels related to the stack segment must match the CPL; that is, the CPL, the RPL of the stacksegment selector, and the DPL of the stack-segment descriptor must be the same. If the RPL and DPL are not equal to the CPL, a general-protection exception (#GP) is generated.

Emphasis mine

That is, SS requires a data segment with DPL equals to 0 when loaded from kernel (or during switches).
This is true for 32 bit mode.

In 64 bit mode, it is possible to use a NULL selector to suppress any runtime check (including the previous one)1

In 64-bit mode, the processor does not perform runtime checking on NULL segment selectors. The processor does not cause a #GP fault when an attempt is made to access memory where the referenced segment register has a NULL segment selector.

Out of completeness, when performing a stack operation all the relevant information, address size, operand size and stack-address size, are either recovered from the code segment or are implicitly set to 64 bits.


1 If I remember correctly, 64 bit mode still use a kernel data segment though, for compatibility reasons.

Upvotes: 5

Related Questions