xv6, line by line
tour 41
Tours41 Every transition: mode, stack and page table

Tour 41 · The dance of privilege · about 27 minutes · 20 steps

Every transition: mode, stack and page table

Freeze xv6 at any instruction, on any hart, and ask three questions. Which privilege mode? User, supervisor or machine. Which stack? Whatever memory sp points into. Which page table? Whatever satp names. If you can answer all three at every instruction, you understand where the hart is. This is the master question of this group of tours (Mode, stack and page table: the master question).

The answers change only at a handful of places, and every change is one of eight transitions:

Transition Mode
T1 system call (ecall) U → S
T2 exception in user code U → S
T3 device interrupt in user mode U → S
T4 timer interrupt in user mode U → S
T5 return to user (sret) S → U
T6 context switch (swtch) S → S
T7 trap taken in the kernel (kernelvec) S → S
T8 boot (mret) M → S

This tour visits the code where each one happens, at commit 06aad25, and ends with the full table of mode/stack/page-table combinations that can exist. The later tours of the group zoom in: Tour 42: One hart's stacks, from power-on to the first user instruction on stacks, Tour 43: A system call, CSR by CSR on a system call’s CSRs, Tour 44: One interrupt, three landing sites on interrupts.

Best after: 2. Power-on to main, on every hart at once, 5. Life of a system call, 13. swtch and the lock handed across a context switch

Who is running where

The story moves between three harts:

Hart What it is doing
0 Booting (T8), then scheduling
1 Running cat README (pid 3): T6, T5, T1 and its relatives
2 Earlier: the shell (pid 2) printing its $ prompt when a tick arrives, a trap taken inside the kernel (T7)

The shell (pid 2) is waiting for cat.

Three harts are running. This tour follows one path through the code, but the machine has three CPUs executing at the same time. Watch the locks held display at the top of each step, and read the Meanwhile, on other harts boxes: they show what the other CPUs could be doing at that very moment.
The route
  1. 1T8: the only way down is a return kernel/start.c
  2. 2Boot's other change, paging on kernel/vm.c
  3. 3main becomes the scheduler, a role change only kernel/main.c
  4. 4T6: the scheduler chooses cat kernel/proc.c
  5. 5T6: one load moves sp kernel/swtch.S
  6. 6T5, part 1: prepare_return arms the way out kernel/trap.c
  7. 7T5, part 2: the page table goes first kernel/trampoline.S
  8. 8T5, part 3: sp, then the mode kernel/trampoline.S
  9. 9T1: cat calls read, and ecall changes only the mode user/usys.S
  10. 10T1–T4, entry: uservec in supervisor mode with user everything kernel/trampoline.S
  11. 11T1–T4, entry: a kernel sp before a kernel page table kernel/trampoline.S
  12. 12T1–T4, entry: csrw satp, and everything is kernel kernel/trampoline.S
  13. 13usertrap: one entry, four transitions kernel/trap.c
  14. 14T2: an exception, survived or fatal kernel/trap.c
  15. 15T3 and T4: devintr reads the cause kernel/trap.c
  16. 16T4 leads to T6: yield and sched kernel/proc.c
  17. 17T7: a trap while already in the kernel kernel/kernelvec.S
  18. 18T7, the way back: kerneltrap and sret to S-mode kernel/trap.c
  19. 19Every combination that exists kernel/trampoline.S
  20. 20Five myths, and is there a ninth transition? kernel/swtch.S

Keys: ← → step · Home start