HW5: System Calls

This homework asks you to extend the xv6 kernel with a simple system call.

You will work with the source code of the xv6 operating system, hence you should use the same setup as for the HW4: Shell.

Write protect system call

Your goal is to add a new system call to the xv6 kernel. The main point of the exercise is to learn some of the different pieces of the system call machinery.

Your new system call will write protect a region of memory that contains a specified virtual address and has a specified size. Specifically, if the user program invokes this new system call the system call removes the write permissions from all pages that contain the specified region of memory.

Your new system call will have the following interface:

int wrprotect(void *addr, int size); 

Note, that you should check that the system call arguments are safe: i.e., the addr points to the valid address in user memory, and the entire region is within the range of valid user addresses (i.e., inside the allocated user memory). You should understand how these checks are done in by looking at other system calls (e.g., read() is a good example).

In order to test your system call you should create a user-level program wrprotect that calls your new system call. Similar to how you did for the nsh shell you should add wrprotect to the xv6 Makefile.

When you're done, you should be able to invoke your wrprotect program from the shell.

Your strategy for making the wrprotect system call should be to clone all of the pieces of code that are specific to some existing system call, for example the "uptime" system call or "read". You should grep for uptime in all the source files, using grep -n uptime *.[chS].

Some hints

The walkpgdir() is a handy function to get the page table entry. Then your only job is to remove the R/W flag.

To test your program allocate some memory with the sbrk() system call and then write protect it. A properly protected address should allow reads, but crash the program on writes.

Make sure your code handles memory regions that span multiple pages.

Extra credit (10%): Print out the crashing ip address

When your test program tries to access the write protected page you should print out the basic crash information (note you should verify that the true reason for the crash is violation of the page protection, not some other reason, i.e., you can walk the page table and verify that the R/W bit is not set).

You should output:

 is trying to access a write protected page at: , ip: 

Extra credit (5%): Print the backtrace of the crashing program

Print the backtrace of the crashing program. First you print all general registers, and then the return addresses saved on the stack.

eax:0x16
ebx:0xbfa8
...
esp:0x2f9c
eip:0x369
ebp:0x2fa8
#0  0x4c
#1  0x6c
#2  0x16
#3  0xffffffff

Extra credit (5%): Unprotect the page and let program run

After you print the basic exit info unprotect the page and let the program run

Submission

Please submit code to Gradescope Gradescope. You have to submit a compressed (zipped) archive of your xv6-public folder. If you submit the extra credit assignment you should add the extra{1,2,3}.txt files that explains what you have done and how it works. You can resubmit as many times as you wish. The structure of the zip file should be the following:
./xv6-public
   | - all xv6 files
   | - wrprotect.c
   | - extra1.txt
   | - extra2.txt
   | - extra3.txt
Updated: November, 2019