Test yourself · category 3 of 20
Traps and system calls How a user program asks the kernel for a service, what ecall and the trap path do, how usertrap and kerneltrap sort traps by scause, and how a system call’s number, arguments and result travel through the trapframe.
All Not yet answered Got wrong Reset this category
echo calls write(1, "hi", 2). What is write in user space?
Check Try again
How does the kernel know which system call the program asked for, and where does
syscall read that information?
kernel/syscall.c
144 // Use num to lookup the system call function for num, call it,
145 // and store its return value in p->trapframe->a0
Check Try again
In our gdb run, echo’s ecall for write sits at user address 0x354. When the system
call finishes, at what address does echo continue? (Answer in hex.)
kernel/trap.c
51 // save user program counter.
60 // sepc points to the ecall instruction,
61 // but we want to return to the next instruction.
Check Try again
4 warm-up True or false, and why True or false: when a user program executes ecall, the hardware switches sp to the
process’s kernel stack.
Check Try again
Why does usertrap add 4 to p->trapframe->epc for a system call?
kernel/trap.c
51 // save user program counter.
60 // sepc points to the ecall instruction,
61 // but we want to return to the next instruction.
64 // an interrupt will change sepc, scause, and sstatus,
65 // so enable only now that we're done with those registers.
Check Try again
The first thing usertrap does after its SPP check is point stvec at
kernelvec (line 47). Why?
kernel/trap.c
43 panic ( "usertrap: not from user mode" );
45 // send interrupts and exceptions to kerneltrap(),
46 // since we're now in the kernel.
Check Try again
8choose… store/AMO page fault load page fault environment call from U-mode (a system call) illegal instruction supervisor external interrupt (a device, through the PLIC) supervisor timer interrupt 13choose… store/AMO page fault load page fault environment call from U-mode (a system call) illegal instruction supervisor external interrupt (a device, through the PLIC) supervisor timer interrupt 15choose… store/AMO page fault load page fault environment call from U-mode (a system call) illegal instruction supervisor external interrupt (a device, through the PLIC) supervisor timer interrupt 2choose… store/AMO page fault load page fault environment call from U-mode (a system call) illegal instruction supervisor external interrupt (a device, through the PLIC) supervisor timer interrupt 0x8000000000000005choose… store/AMO page fault load page fault environment call from U-mode (a system call) illegal instruction supervisor external interrupt (a device, through the PLIC) supervisor timer interrupt 0x8000000000000009choose… store/AMO page fault load page fault environment call from U-mode (a system call) illegal instruction supervisor external interrupt (a device, through the PLIC) supervisor timer interrupt
Check Try again
8 solid Choose all that apply Which of these does the hardware itself change when a user program executes ecall?
Check Try again
For a system call, usertrap turns interrupts on at line 66, but only after line 52
and the scause test. Why not earlier?
kernel/trap.c
51 // save user program counter.
60 // sepc points to the ecall instruction,
61 // but we want to return to the next instruction.
64 // an interrupt will change sepc, scause, and sstatus,
65 // so enable only now that we're done with those registers.
Check Try again
Click the line that delivers sys_write’s result to the user program.
kernel/syscall.c
144 // Use num to lookup the system call function for num, call it,
145 // and store its return value in p->trapframe->a0
Your pick: none yet (click a line in the code)
Check Try again
A buggy program puts 99 in a7 and executes ecall. What happens in this kernel?
kernel/syscall.c
144 // Use num to lookup the system call function for num, call it,
145 // and store its return value in p->trapframe->a0
Check Try again
What is NELEM(syscalls), the number of elements in the table?
kernel/syscall.c
107 // An array mapping syscall numbers from syscall.h
108 // to the function that handles the system call.
Check Try again
Check Try again
14 solid Choose all that apply A timer interrupt arrives while cat runs in user mode (it has not been killed). Which of
these does usertrap do for this trap?
kernel/trap.c
43 panic ( "usertrap: not from user mode" );
45 // send interrupts and exceptions to kerneltrap(),
46 // since we're now in the kernel.
51 // save user program counter.
60 // sepc points to the ecall instruction,
61 // but we want to return to the next instruction.
64 // an interrupt will change sepc, scause, and sstatus,
65 // so enable only now that we're done with those registers.
74 // page fault on lazily-allocated page
84 // give up the CPU if this is a timer interrupt.
90 // the user page table to switch to, for trampoline.S
93 // return to trampoline.S; satp value in a0.
Check Try again
15 deep Fill in the machine state A user program stores to a lazily allocated heap page and takes a store page fault
(scause 15). usertrap calls vmfault . What is the state of the hart at line 463,
before kalloc has been called?
Privilege mode choose… M (machine) S (supervisor) U (user) Active stack choose… user stack the process's kernel stack scheduler stack (stack0) boot stack (stack0) no usable stack Page table (satp) choose… paging off kernel page table user page table Interrupts (sstatus.SIE) choose… on off noff choose… 0 1 2 3 4 intena choose… 0 1 — (noff is 0)
Check Try again
Inside usertrap , scause reads 0x8000000000000009. Decode it.
Value: 0x8000000000000009
Bit 63 choose… 1: an interrupt 0: an exception Code (the low bits) choose… 9 8 5 Meaning choose… supervisor external interrupt (a device, through the PLIC) supervisor timer interrupt environment call from U-mode What devintr returns choose… 1 2 0 Will usertrap call yield() for this trap? choose… no yes Check Try again
17 solid True or false, and why True or false: if a user program sets sp to 0 just before its ecall, it can crash the
kernel.
Check Try again
Put these steps of one system call (one that does not sleep or yield) in the order they
happen.
syscall runs the handler and stores its result in trapframe->a0↑ ↓ uservec saves the user registers into the trapframe↑ ↓ uservec loads the kernel stack and switches satp to the kernel page table↑ ↓ userret switches to the user page table, restores the registers and executes sret↑ ↓ usertrap turns interrupts on↑ ↓ ecall: mode U to S, sepc = the ecall’s address, pc = stvec↑ ↓ prepare_return turns interrupts off and points stvec at uservec↑ ↓ usertrap copies sepc into p->trapframe->epc↑ ↓ Check Try again
kernel/trap.c
134 // interrupts and exceptions from kernel code go here via kernelvec,
135 // on whatever the current kernel stack is.
145 panic ( "kerneltrap: not from supervisor mode" );
147 panic ( "kerneltrap: interrupts enabled" );
150 // interrupt or trap from an unknown source
156 // give up the CPU if this is a timer interrupt.
160 // the yield() may have caused some traps to occur,
161 // so restore trap registers for use by kernelvec.S's sepc instruction.
Check Try again
kernelvec restores every register it saved except tp; it does not even save it. Why?
kernel/kernelvec.S
44 # not tp (contains hartid), in case we moved CPUs
63 # return to whatever we were doing in the kernel.
Check Try again
Suppose usertrap called intr_on() right after line 47 (so before line 52), and a timer interrupt was
already pending when echo executed its ecall for write. What would happen?
kernel/trap.c
51 // save user program counter.
60 // sepc points to the ecall instruction,
61 // but we want to return to the next instruction.
64 // an interrupt will change sepc, scause, and sstatus,
65 // so enable only now that we're done with those registers.
Check Try again
22 deep Choose all that apply In this kernel, which of these traps from user mode end with usertrap killing the
process?
kernel/trap.c
74 // page fault on lazily-allocated page
Check Try again
cat is inside copyout (in a system call, interrupts on) when hart 2’s timer fires.
Put the steps in order.
kerneltrap copies sepc and sstatus into local variables↑ ↓ The hardware sets sepc to the interrupted instruction, scause to the timer code, clears SIE, and jumps to stvec, which is kernelvec ↑ ↓ kernelvec pushes a 256-byte frame on cat’s kernel stack and saves the caller-saved registers↑ ↓ devintr calls clockintr , which writes a new stimecmp↑ ↓ kernelvec reloads the registers, pops its frame and executes sret↑ ↓ yield switches away; later cat resumes, perhaps on another hart↑ ↓ kerneltrap writes the saved sepc and sstatus back↑ ↓ Check Try again
Hart 1 has nothing to run. Its scheduler briefly enables interrupts at line 441, and a
timer interrupt is taken there. What does kerneltrap do?
kernel/trap.c
150 // interrupt or trap from an unknown source
156 // give up the CPU if this is a timer interrupt.
160 // the yield() may have caused some traps to occur,
161 // so restore trap registers for use by kernelvec.S's sepc instruction.
Check Try again
During one system call that neither sleeps nor yields, how many times is stvec written,
from the ecall to the sret?
Check Try again
← RISC-V privilege and CSRs All categories Trampoline and trapframe →