JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

Protection, Privilege, and Isolation

One machine runs your browser, your music player, and an operating system all at once — and a bug or a malicious tab must not be able to read your passwords out of another program's memory. This guide shows the hardware that draws those walls: privilege levels, the MMU, and the virtualization support that lets whole operating systems share one chip without trampling each other.

From not-failing to not-betraying

The previous guide worried about a single program being correct: a cosmic ray flips a bit, ECC catches and repairs it, and the machine keeps computing the right answer. That is one face of trustworthiness — reliability, the machine not failing by accident. This guide turns to a sharper face: the machine not betraying you on purpose. On any real computer, dozens of programs you do not fully trust — web pages, downloaded apps, that one sketchy game — run side by side on the same processor and the same physical RAM. The hardware's job is to make sure none of them can reach into another's secrets, or seize control of the whole machine.

Why must the hardware do this? Because software alone cannot. If protection were merely a rule the operating system politely asked everyone to follow, the first buggy or hostile program would simply ignore the rule. Walls that anyone can step over are not walls. So the processor itself enforces two foundations in silicon: privilege, which decides who is allowed to do dangerous things, and isolation, which decides what memory each program can even see. Get these two right and you can run untrusted code safely; get them wrong — as we will see in the Spectre and Meltdown guides — and the whole edifice leaks.

Privilege levels: a king and his subjects

The first wall divides the world into two kinds of citizen. The processor runs in one of several privilege levels: the most trusted is kernel mode (also called supervisor mode), where the operating system lives, and below it is user mode, where your applications run. Think of it as a kingdom with a king and his subjects. The king may touch anything — the page tables, the device controllers, the timer that decides who runs next. A subject may only do ordinary, safe work: arithmetic, branches, reading and writing its own memory. Certain instructions are privileged: try to execute one in user mode and the hardware refuses, raising a fault instead.

But subjects sometimes genuinely need the king's help — to open a file, send a packet, or ask for more memory. They cannot just jump into kernel code; that would defeat the whole point. Instead they use a controlled doorway, the system call. A special instruction (on RISC-V it is `ecall`) traps into the kernel at one fixed, blessed entry point, switches the processor to kernel mode, and hands control to code the operating system chose in advance. The kernel checks the request, does the privileged work on the subject's behalf, then returns to user mode. The crucial detail is that user code never picks where in the kernel it lands — only that it knocks on the one official door.

Isolation: the MMU as gatekeeper

Privilege says who may act; isolation says what each program can see. The mechanism reuses something you already met two rungs ago. Recall virtual memory: every program believes it owns the whole house, address 0x0 up to the top, while a quiet translator maps its rooms to wherever they really sit in physical RAM. That translator is the memory management unit, the MMU, and it does far more than translate — on every memory access it also acts as a gatekeeper, checking whether this access is even allowed. Translation and protection are the same machinery; this is why virtual memory is not 'extra RAM' but address translation plus protection.

Here is where the magic of process isolation lives. Each program gets its own set of page tables, and the kernel — running as the king — sets them up so that a program's virtual addresses map only to physical frames the kernel handed it. Program A's page tables simply contain no entry pointing at Program B's frames. So even though both run on the same RAM, A literally has no way to name a byte that belongs to B; the address it would need does not exist in A's map. Two programs editing 'the same' address 0x4000 are quietly steered to two different physical pages, never colliding. The walls are not painted on the RAM — they are baked into whose translations point where.

Each page-table entry also carries a few permission bits that the MMU checks on every access. Typically: may this page be read, written, or executed, and is it accessible from user mode or kernel-only? These give memory protection its teeth. A page holding program code is marked read-and-execute but not writable, so a bug cannot rewrite the program as it runs. A page holding data is read-write but not executable, so an attacker who sneaks data into a buffer cannot then jump to it and run it. And kernel pages are flagged kernel-only, so a user program that tries to read them faults instantly — at least, that was the iron rule, until Meltdown showed a crack in exactly this check.

A protected access, step by step

Let us trace one ordinary load through the gatekeeper to see protection and translation happen together. Suppose a user-mode program executes a load from virtual address 0x4008 — say, the eighth byte of a page. Walk it through:

  1. The processor splits the virtual address into a page number and an offset within the page, and hands the page number to the MMU.
  2. The MMU checks the TLB — the small fast cache of recent translations. On a hit it has the physical frame and the permission bits in one cycle; on a TLB miss it walks the page table in memory to find them.
  3. It checks the permission bits against this access: is the page present, is it readable, and is user-mode access allowed? If any check fails, the MMU raises a fault and the load never touches memory.
  4. On a fault, control traps into the kernel — exactly like a system call's controlled doorway — and the king decides what to do: kill the offending program, or quietly fix things up and retry.
  5. Only if every check passes does the MMU combine the physical frame with the offset into a real physical address, and the load finally reads RAM.

Notice that the permission check sits in the translation path itself: there is no extra step the kernel must remember to insert, and no instruction a program can run to skip it. Every single memory reference your program makes — billions per second — is silently vetted by hardware. That is the only reason it is cheap enough to be always-on: it rides along on translation you were paying for anyway, and a TLB hit makes the common case effectively free.

Virtualization: kings above kings

Now stretch the idea one level higher. A cloud server may run several whole operating systems at once — your virtual machine and a stranger's, on the same physical chip. Each guest OS still thinks it is the king, freely setting up page tables and handling its own system calls. But there must be a new super-king above all of them: the hypervisor, running at a privilege level above kernel mode, that hands each guest its slice of RAM and its share of the cores, and isolates the guests from one another exactly as the kernel isolates ordinary programs — only one tier up.

The hard part is memory. A guest program's address must be translated twice: from the program's virtual address to the guest OS's notion of physical memory, and then from there to the real physical RAM the hypervisor actually granted. Doing this in software was painfully slow, so chips grew explicit virtualization support — nested page tables (Intel's EPT, AMD's NPT) that let the MMU perform both translations in hardware in one walk. This is a recurring theme of this whole subject: a security or abstraction boundary that is expensive in software gets specialized into silicon to make it cheap, because protection you cannot afford to run is protection nobody turns on.