Search code examples
assemblyx86privilege

Current x86 privilege level on a custom OS


In a custom OS running on an x86 in protected mode, is there a way to obtain the current privilege level, other than e.g. executing a privileged instruction and seeing if it crashes?

For instance, register CR0 contains the PE bit, which indicates if we are running on real mode or protected mode, and can be easily retrieved using assembly code.

Is there something equivalent for the privilege level?

The Intel architecture software developer manual mentions that the EFLAGS register contains two IOPL bits related to I/O privilege levels. Is this the same as the current privilege level (CPL)?


Solution

  • No it's not the same. Those represent the io privilege level. Some instructions such as IN, OUT, CLI require io privileges which are determined using the IOPL and the CPL.

    See also:

    IOPL I/O privilege level field (bits 12 and 13) -- Indicates the I/O privilege level (IOPL) of the currently running program or task. The CPL of the currently running program or task must be less than or equal to the IOPL to access the I/O address space.

    The CPL can be read simply from the CS selector as the two lowest bits:

    mov ax, cs
    and ax, 3
    

    This of course only works in protected mode.