HW5: System Calls

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

You will program the xv6 operating system, so you should use the same setup as for the HW2: Xv6 boot.

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). Please return -1 if the arguments for the function are incorrect.

In order to test your system call we recommend you to 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.

The testing of the gradescope would be done by creating custom program which would use your system call.

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 (5%): Print out the crashing ip address

When your system call 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:

Program is trying to access a write protected page at: {addr}
For example: Program is trying to access a write protected page at: 0xAABBCCDD

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. Plese use exact formatting provided below:

eax:0x16
ebx:0xbfa8
ecx:0x1
edx:0x21
esi:0x6b1a
edi:0x2a1a
esp:0x2f9c
ebp:0x2fa8
eip:0x369
#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:
/
  - /mainPart
    - all xv6 files
    - wrprotect.c
  - /extraPart
    - all xv6 files
    - wrprotect.c
    - extra1.txt    -- optional
    - extra2.txt    -- optional
    - extra3.txt    -- optional
 
	  
Updated: May, 2020