9

I read in "INTEL 80386 PROGRAMMER'S REFERENCE MANUAL" (p112, S 6.3.1.3) that

An internal processor register records the current privilege level (CPL).

I am curious as to what register it refers to. Does it even have a name? What's the size of the register? Does it have any other use?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
xtt
  • 857
  • 1
  • 8
  • 24

1 Answers1

9

The Current Privilege Level (CPL) can always be found in the lower 2 bits of the Code Segment (CS) register. Those 2 bits can be the value 0b00 (ring 0), 0b01 (ring 1), 0b10 (ring 2), 0b11 (ring 3).

It should be noted that the old documentations use of "An internal processor register records the current privilege level (CPL)" is a bit deceptive and has caused some head scratching for others as well. CS always contains the CPL in the lower 2 bits but obviously it isn't an internal register.

The microarchitecture may have a copy of the CPL internally as well, but it is always accessible programmatically by looking at CS.

Not directly related to your question, but may be useful to know. If you transitioned between different rings and the destination code segment selector had a descriptor that is a conforming segment, it's possible for the Descriptor Privilege Level (DPL) != CPL. This is because with a conforming segment you continue to run with the previous privilege level. With non-conforming segments DPL == CPL.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • Thanks for the prompt reply. But I am a little confused, since CS will be used to store a segment selector, which has the lower 2 bits as the RPL, how can the same location be used to store CPL? – xtt Sep 13 '19 at 15:16
  • @xtt: If I understand correctly: If the "request" is allowed, it becomes the current. Otherwise it faults and CS never takes the requested value. i.e. RPL is the low 2 bits of something that you're trying to *make* current. – Peter Cordes Sep 15 '19 at 11:18
  • 1
    I think the reason it is distinguished is because the cpu causes some requests independent of the current context. This permits interrupts and faults to be secured against the *int* instruction. For example, issuing an *int $14* could confuse the kernel since the stack frame would be wrong, and might open an exploit. – mevets Sep 18 '19 at 18:02