Virtual Memoryprivilegekernel modeuser moderingsisa

Why Kernel Mode Is Actually Privileged

User mode and kernel mode are not a convention the kernel politely observes. They are a hardware state, and the CPU refuses certain instructions and certain memory outright depending on which one it is in.

Follow the mechanism

Software view, hardware view

The gap between what you wrote and what the machine does is where this whole domain lives.

The question
What makes kernel mode actually privileged, rather than just a convention the kernel follows?
What you wrote
The kernel is trusted code that can do more than my program. Presumably it checks who is calling and decides what to allow.
What the hardware does
The CPU holds a current privilege level as architectural state. Certain instructions and certain page mappings are refused outright in the less privileged state, by the hardware, without any software being consulted. Raising the level cannot be done by simply setting a register — it requires a controlled transition to an address the kernel chose in advance.
If privilege were a software convention, any bug that let you run code would let you run privileged code. Because it is hardware state changeable only through controlled entry points, an attacker who gets arbitrary user-mode execution still faces a genuine boundary — which is why privilege escalation is a distinct and harder step from code execution.
SourceCompilerInstructionsFront EndExecutionRegistersCachesMemoryI/OBehavior

The mode is state, and it gates the instruction set

The CPU tracks a current privilege level the same way it tracks a program counter: as architectural state that affects how every subsequent instruction is interpreted. In the less privileged state, a set of instructions simply does not work — attempting one faults rather than executing.

Which instructions? Broadly, the ones that would let you dismantle the protections. Loading the page-table base register would let you install your own mappings. Modifying the interrupt vector table would let you intercept the kernel. Halting the processor, accessing device registers directly, changing the privilege level itself — all gated.

The critical property is that the gate is not a check the kernel performs. There is no kernel code involved when a user-mode program attempts a privileged instruction; the hardware refuses it. This is why "the kernel forgot to check" cannot produce a privilege escalation on its own — the kernel was never asked.

What the privilege level gates — categories, not an exhaustive list
CapabilityWhy it is privilegedWhat it would allow otherwise
Loading the page-table baseControls all translationMapping any physical memory into your address space
Editing interrupt/exception vectorsControls where traps goIntercepting or bypassing kernel entry
Direct device register accessBypasses OS mediationDriving hardware, including DMA to arbitrary memory
Halting or resetting the CPUDenial of serviceStopping the machine from user code
Changing the privilege levelThe boundary itselfTrivially becoming the kernel
Accessing supervisor-only pagesEnforced per access by the MMUReading or writing kernel memory directly

You cannot simply set the bit

The obvious attack on this scheme is to change the privilege level yourself. The hardware forecloses it: there is no instruction available in user mode that raises privilege arbitrarily. The level changes only through specific, controlled events — a trap, an interrupt, an exception, or the dedicated system-call instruction.

What makes those controlled is that they do not merely raise the privilege level; they simultaneously transfer control to an address the kernel installed in advance. You cannot become privileged *and* choose where execution continues. The entry point is the kernel's, always, and the kernel's first instructions run before any attacker-chosen code can.

This pairing is the whole design. Raising privilege without redirecting control would be a hole; redirecting control without raising privilege would be useless. Coupling them means every path into the privileged state passes through code the kernel wrote — which is why Why a System Call Costs More Than a Function Call is a hardware mechanism rather than a calling convention.

executesnot permitted at this levelthe only legitimate routehardware jumps hereprivilege raised together with control transferUser modePrivileged instruction?Syscall / trap / interruptFault — refusedKernel-chosen entry pointKernel mode
UserLLMAgentToolDataDecisionHumanGuardrail

Rings, exception levels and why the count varies

ISA-SPECIFICx86 rings 0–3 (mainstream systems use 0 and 3), AArch64 EL0–EL3, RISC-V machine/supervisor/user. The counts, names and exact capabilities differ substantially; only the ordered-privilege structure is common.

Different architectures name and count these levels differently, and the naming causes more confusion than the concept warrants. x86 defines four rings, of which mainstream operating systems use two. AArch64 defines exception levels with a distinct level for hypervisors and another for secure firmware. RISC-V defines machine, supervisor and user modes.

What matters is not the count but the structure: a strict ordering where more privileged levels can do everything less privileged ones can and more, and where transitions upward are only possible through controlled entry points. Every design has that shape even where the vocabulary differs completely.

Virtualization is what motivated the extra levels. A hypervisor must be more privileged than a guest kernel that itself believes it is fully privileged, which requires a level above the one the guest occupies. That is why AArch64 has a dedicated hypervisor level and why x86 grew virtualization extensions rather than repurposing an existing ring — What a vCPU Actually Is takes this further.

The same structure, three vocabularies
ArchitectureLeast privilegedOS kernelAbove the kernel
x86-64Ring 3 (user)Ring 0 (kernel)VMX root mode for hypervisors
AArch64EL0 (application)EL1 (kernel)EL2 (hypervisor), EL3 (secure monitor)
RISC-VU-mode (user)S-mode (supervisor)M-mode (machine), plus optional H extension

Key points

  • The privilege level is architectural hardware state, not a software convention or a kernel-maintained flag.
  • Privileged instructions fault in user mode with no kernel code involved in refusing them.
  • Privilege can only be raised through controlled transitions that simultaneously transfer control to a kernel-chosen address.
  • Coupling privilege escalation to control transfer is the core of the design; either alone would be useless or unsafe.
  • Architectures differ in count and naming, but all implement the same ordered structure with controlled upward transitions.

Follow the mechanism

The path through the machine, hop by hop — and the conclusions it invites that are wrong.

  1. 1
    CPU → current level: the privilege level is held as architectural state, consulted for every instruction and every access.
  2. 2
    Instruction → decode: a privileged instruction attempted at a lower level faults instead of executing.
  3. 3
    MMU → supervisor bit: pages marked supervisor-only are refused for user-mode accesses on the same check as any other permission.
  4. 4
    Syscall/trap → vector: a controlled event raises the level and jumps to an address the kernel installed in advance, in one indivisible step.
  5. 5
    Return → user: a dedicated return instruction lowers the level and restores the saved user context.
What people conclude from this — wrongly
  • Believing the kernel checks a caller's identity to decide what to permit; the hardware refuses privileged operations before any kernel code runs.
  • Assuming code execution implies privilege escalation. They are distinct, and the second requires defeating a hardware boundary.
  • Treating ring numbers as meaningful across architectures — the vocabulary differs and the counts do not correspond.
  • Thinking the kernel is protected by a mechanism separate from ordinary paging; the supervisor bit is checked on the same lookup as everything else.

Consequences, controls and cost

What it causes
  • • Arbitrary user-mode code execution does not imply kernel access; escalation is a separate and substantially harder step.
  • • Every entry into the kernel begins at code the kernel chose, so the kernel can validate arguments before doing anything.
  • • Device access must be mediated by the kernel, which is why user-space drivers require explicit privileged setup.
  • • Hypervisors need a level above the guest kernel, which is why virtualization required architectural extensions.
  • • The kernel's own memory is unreachable from user mode through the ordinary permission bits, not a separate mechanism.
What you can do
  • • Treat the boundary as the security-relevant one: reducing the number of crossings matters more for performance than for safety.
  • • Batch work across the boundary rather than crossing repeatedly — the cost is per crossing, not per byte ([[system-call-transition]]).
  • • For device-adjacent work, use the kernel's provided interfaces rather than seeking direct access; the gate is not negotiable from user mode.
  • • Otherwise: nothing. You cannot change the privilege level from user code, which is precisely the point.
How to see it
  • • Count system calls with `strace -c` or equivalent — crossing frequency is the number that matters for performance.
  • • Compare cycles spent in user versus kernel mode (`perf stat` reports both) to see how much of a workload lives across the boundary.
  • • Watch for workloads with high kernel-mode time and small payloads per call; that pattern usually means batching would pay.
  • • Inspect which mappings are supervisor-only in a process map to see the boundary as the MMU sees it.
What it costs
  • • A hard hardware boundary gives strong isolation at the cost of making every legitimate crossing expensive.
  • • More privilege levels enable virtualization but add architectural complexity and lengthen some transition paths.
  • • Controlled entry points mean the kernel can validate everything, at the cost of every entry funnelling through a small number of paths.

Scope

§224 — what these claims are specific to.

What these claims are specific to
  • ISA-SPECIFICx86 rings, AArch64 exception levels and RISC-V modes differ in count, naming and capability. Only the ordered structure with controlled upward transitions is common to all.
  • GENERALThe existence of a hardware-enforced privilege boundary holds across application-class CPUs. MMU-less microcontrollers frequently have no such separation and run everything privileged.

Misconceptions

Claim
“Kernel mode is a software convention the kernel enforces on itself.”
Reality
It is architectural CPU state. Privileged instructions fault in user mode with no kernel involvement, which is why it holds even against code the kernel never sees.
Claim
“If an attacker can run code, they can run kernel code.”
Reality
Raising privilege requires a controlled transition to a kernel-chosen address. That is why escalation is a separate vulnerability class from execution, and a rarer one.
Claim
“Ring 0 and EL1 are the same thing with different names.”
Reality
They occupy similar positions but the architectures differ in level count, capabilities and transition mechanisms. AArch64 has dedicated hypervisor and secure levels with no direct x86 ring equivalent.