5.1.13 · D4Instruction Set Architecture (ISA)

Exercises — System vs user mode and privilege levels

2,362 words11 min readBack to topic

Before we start, one convention used throughout:

Figure — System vs user mode and privilege levels

Level 1 — Recognition

Recall Solution 1.1

(a) P. Disabling interrupts could let a program freeze the machine — kernel-only. (b) U. Pure arithmetic touches nothing dangerous. (c) P. Halting the CPU stops everyone — kernel-only. (d) P. cr3 holds the page-table base; changing it re-maps all memory — kernel-only. (e) U. Writing to the program's own stack is fine.

Count: 3 privileged (a, c, d), 2 unprivileged (b, e).

Recall Solution 1.2

False. Privilege is inverted: the lower number is more trusted. = kernel (most power), = user (least). Remember the parent's mnemonic "Ring 0 = King."


Level 2 — Application

Recall Solution 2.1
  1. Decode: the instruction decoder recognises cli as privileged (see Instruction encoding and decoding).
  2. Compare: required level , current level . Since and the instruction demands the most privileged level, this is a violation.
  3. Trap: the hardware raises a #GP (General Protection Fault) — an exception. It does not execute cli.
  4. Transfer: control jumps atomically to the kernel's fault handler (mode→kernel, PC→OS vector).
  5. Outcome: the OS typically terminates the process (signal such as SIGSEGV/SIGILL).

Key number: required , actual , difference fault.

Recall Solution 2.2

Encode the levels numerically: . The rule here is "you may run an instruction if your level is at least the required level."

  • Required . In U (): faults (an illegal-instruction trap).
  • In M (): allowed (Machine mode is even more privileged than Supervisor).

Lesson: always convert the named levels to numbers with the machine's own convention before comparing. x86 uses "smaller = stronger"; RISC-V uses "bigger = stronger". The logic (compare current vs required) is identical.


Level 3 — Analysis

Recall Solution 3.1

Attack:

mov  mode_bit, 0     ; user sets CPL = 0  (allowed, by hypothesis)
cli                  ; now "kernel", so this succeeds -> interrupts off
hlt                  ; freeze the whole machine

Because setting the mode bit was not privileged, the user promoted itself to kernel in one instruction, then ran any privileged op it liked. The referee became bypassable.

Conclusion: writing the mode bit must itself be privileged. This is the fixed point from the parent's Step 3 — the only safe promotion is the hardware-defined syscall doorway, which sets kernel mode and forces PC to an OS-chosen vector at the same time.

Recall Solution 3.2

The privileged resource is the hardware timer. Trace:

  1. Before dispatching the process, the kernel programmed the timer to fire after some quantum (say ). Programming the timer is privileged, so the user cannot cancel it.
  2. The user runs while(1){} — it cannot execute cli (privileged) to block interrupts either.
  3. When the timer counts down to , it raises a timer interrupt. The CPU atomically switches mode→kernel and jumps PC→the timer handler.
  4. The scheduler runs, may pick another process, and returns via iret/sret.

Two independent locks protect this: (i) the user cannot disable the timer, (ii) the user cannot disable interrupts. Break either and pre-emption dies — which is why both are privileged.

Figure — System vs user mode and privilege levels

Level 4 — Synthesis

Recall Solution 4.1
Step Mode What happens Why
1 user library loads syscall number + fd, buf, n into registers fast, ABI-defined, no memory needed
2 user executes syscall/ecall direct disk I/O is privileged; user can't do it itself
3 → kernel HW atomically: mode→kernel, PC→fixed OS entry vector user picks that it enters, never where
4 kernel validate fd is an open file this process owns stop it reading another process's files
5 kernel validate buf..buf+n lies in this process's mapped memory stop tricking the kernel into writing its own memory
6 kernel perform the privileged disk read, copy bytes into buf the actual service
7 → user sret/iret: mode→user, PC→instruction after syscall drop privilege atomically before returning

Two privilege transitions: user→kernel (step 3) and kernel→user (step 7). The whole thing is safe because the entry point is OS-chosen (step 3) and the arguments are validated (steps 4–5) before any privileged action.

Recall Solution 4.2

Suppose they were separate:

step A:  mode <- kernel
step B:  PC   <- OS entry vector

An attacker arranges for an interrupt (or simply the natural sequencing) to hand control between A and B. Now the CPU is in kernel mode but PC still points at attacker-chosen code. The attacker runs their own instructions with full privilege — game over.

By fusing A and B into a single uninterruptible transition, the CPU is never observable in the state "kernel mode + user-controlled PC". Atomicity is precisely what forbids that dangerous intermediate state. This is why the doorway is a single hardware instruction, not a software sequence.


Level 5 — Mastery

Recall Solution 5.1

Minimal privileged set and the collapse if each is made unprivileged:

  1. Write the mode/CPL bit — if user-writable: self-promotion (Exercise 3.1), whole scheme dead.
  2. Load the page-table base register (cr3/satp) — if user-writable: a process re-maps memory to read the kernel's or another process's pages; memory isolation dies.
  3. Disable/enable interrupts (cli/sti) — if user-writable: a rogue loop masks the timer and never yields; pre-emption dies (Exercise 3.2).
  4. Program the hardware timer / interrupt controller — if user-writable: user cancels its own quantum; pre-emption dies even with interrupts enabled.
  5. Direct device I/O (port/MMIO to devices) — if user-accessible: a process reads the raw disk and steals every file, bypassing file permissions.
  6. hlt / power / reset control — if user-accessible: any process halts the machine; availability dies.

Each item guards a distinct invariant (identity, memory isolation, pre-emptibility, timing, I/O confidentiality, availability). Because the invariants are independent, no item can be dropped — remove any one and its invariant is directly violable by user code. Hence this set is both sufficient (covers all invariants) and minimal (no redundancy).

Recall Solution 5.2

Extend the ladder with one more, more-privileged level: On x86 this is the VMX root / non-root split (informally "Ring "); on ARM it is EL2 sitting above the OS's EL1 (see Protection rings (x86) / Exception Levels (ARM)).

The hypervisor must exclusively own the second-level (nested) page tables — the mapping from guest-physical to real-physical memory. Reasoning: the guest OS legitimately controls its own page tables (guest-virtual → guest-physical), so that can't be what isolates guests. What must be off-limits to the guest is the outer translation, or one guest OS could map real RAM belonging to another guest. So the newly-privileged operation is loading the nested/extended page-table base register, reserved to the hypervisor level.

This is the same pattern one level up: whoever enforces isolation between the tenants below it must exclusively own the resource that defines those tenants' boundaries.


Recall One-line summary of the whole ladder (click)

Every privilege level exists to protect one invariant the level below it must not break; the referee is always the hardware, the only legal way up is a hardware-defined doorway (syscall/trap/interrupt) that fixes both the new mode and the new PC atomically.