12/04/2022, 09:17 Exam/System Calls – COMP3231/COMP9201/COMP3891/COMP9283
System Calls and Kernel Entry and Exit
1. System Calls and Kernel Entry and Exit
1. Using a simple system call as an example (e.g.
Copyright By PowCoder代写 加微信 powcoder
getpid, or uptime), describe what is generally involved in providing the result, from the point of calling the function in the C library to the point where that function returns.
2. Why must the operating system be more careful when accessing input to a system call (or producing the result) when the data is in memory instead of registers?
3. Is putting security checks in the C library a good or a bad idea? Why?
Using a simple system call as an example (e.g. getpid, or uptime), describe what is generally involved in providing the result, from the point of calling the function in the C library to the point where that function returns.
The userspace program makes a function call to the C library, e.g. ‘uptime’, which sets up a system call in the appropriate manner for the hardware. The userspace program must set up parameters appropriately then trap, such that the kernel takes control and processes the request in userspace. In MIPS, this is achieved through the syscall instruction.
Once the kernel has control, the user state is saved. The kernel performs necessary security & sanity checks, then attempts to fulfill the request. In the case of ‘uptime’, it would copy the value of a counter, which (presumably) has been counting seconds since powerup. The user state is restored, the counter is placed this in the stack or a register and warps back to userspace. The C library routine reads the stack / register that the kernel just wrote, and returns it to the userspace program.
http://cgi.cse.unsw.edu.au/~cs3231/07s1/lectures/lect03.pdf Its all about system calls, and has the required info. Page 64 has a nice diagram of the process.
The steps may be:
Set up the required syscall arguments
same as a non syscall function, but it also moves the syscall number into register
Run syscall instruction
instead of jal $function_label_here, the assembly is syscall This generates an exception in the CPU. This has the following effect
The program counter changes to 0x8000_0080 (assuming the system has been initialised. Depending on status-register values, this number will be different)
Notice how it’s the beginning of kseg0, but the first bytes leading bit is flipped?
The co-processors c0_epc register holds the value of the PC before it was over-ridden by the exception
https://wiki.cse.unsw.edu.au/cs3231cgi/Exam/System Calls
12/04/2022, 09:17 Exam/System Calls – COMP3231/COMP9201/COMP3891/COMP9283
This is how we know where to go back to The c0_cause register is set
In this case, it will give us the information we need to know that we have to handle a syscall
The c0_status is changed. it gets hit with << 2, and bits 8 to 15 get set
moves "currently in user mode" and "interupts are currently on" bit- values into "previous" parts of that register, which in turn gives theirs to "old"
"currently in user mode" and "interupts currently on" are the right- most bits, so the << 2 gives them 0-values
interupts are off, and CPU is operating in privileged mode, meaning we can do things like mfc0 instructions
Note: for non sys-call kernel entries, you might also have other coprocessor registers set
We want to setup our stack-pointer, but $sp still holds a u-level value. So we first save that to a $k1 register (or 0, whatever)
We also need to check the status context of where we are coming from. bits 8 ot 15 in c0_status, along with a bit-mask will do that
Save c0_status into the other kernel register. and it with a bit mask. This will tell you if you need to fetch a kern-stack or not. If you just got
interupted from the k-stack, you jump over this next bit
We don't need $k0 anymore (only needed it for that branching check), so we load it up with the k-stack we want using
lw $k0 curkstack to get the address of where kstack start is
sw $sp 0($k0) to dereference to the start of the k stack
Now we just need to save the cause with mfc0 $k0 c0_cause
**In changing only these three registers below**, we can start changing context
$k1 to hold previous stack pointer
$sp has current stack pointer, this allows us to change $sp to the correct
$k0 to hold status (lecture, os161 source code says curcpu) Change to kernel stack (see above)
Preserve registers by saving to memory (the stack)
This happens by manually using lw assembly instruction to put the value of each register to a particular spot in memory, such that we can give $a0 a memory address this is effectively pointing to a trapframe struct, for when we do a jal
We don't just preserve the normal registers, we also preserve co processor registers, and the previous stack-pointer
Now, we have a kernel-context, and a saved user-context
jal mips_trap (C code, yay!)
This is where we can use the information in the user-stack, and how we got here, to enter into the kernel code. Do we go to read()? read up on where $v0 got saved, to find out
Do the read()
Restore registers
Switch back to user stack
we do this by loading up a $k1/0 register to hold the return address of the PC we saved from c0_epc when first entered with a syscall
we then jr $k0/1 and in the branch delay slot, rfe the jr puts us back to where we came from
https://wiki.cse.unsw.edu.au/cs3231cgi/Exam/System Calls
12/04/2022, 09:17 Exam/System Calls - COMP3231/COMP9201/COMP3891/COMP9283
rfe puts the cpu back into the same mode as where we came from (roughly)
Return to application
Why must the operating system be more careful when accessing input to a system call (or producing the result) when the data is in memory instead of registers?
The operating system needs to verify that the memory being written to / read from is a valid address, owned by the process making the request. It must prevent processes from corrupting other processes, or reading memory owned by other processes. The operating system must take care with inputs from memory as:
a. The address given by the application as the address of the input or output could be
an address of an illegal area of memory
an address of a legal area that is paged to disk
b. or, could change if the application is multithreaded.
Basically, the operating system must ensure that it cannot be corrupted, crashed, or bypassed as a result of accessing memory as directed by the application.
Is putting security checks in the C library a good or a bad idea? Why?
Putting security checks in the C library is no guarantee of security, because it is the choice/convenience of the userspace program to use the C library. There is nothing to stop a userspace program making a system call directly, with whatever parameters it pleases, which are potentially malicious. Security checks should be performed in kernel space, where the userspace program has no influence, and cannot circumvent security checks.
Exam/System Calls (last edited 2019-05-10 17:28:01 by BenjaminPietersHawke)
https://wiki.cse.unsw.edu.au/cs3231cgi/Exam/System Calls
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com