
page_fault 함수 실행. 내부에 page_fault 구체적인 사유를 알기 위해 비트3개 사용 결과를 알기 쉽도록 변수에 저장한 뒤, vm_try_handle_fault 로 전달 우리가 구현해야하는 핸들러가 vm_try_handle_fault에 해당된다.
page_fault (struct intr_frame *f) {
bool not_present; /* True: not-present page, false: writing r/o page. */
bool write; /* True: access was write, false: access was read. */
bool user; /* True: access by user, false: access by kernel. */
void *fault_addr; /* Fault address. */
/* Obtain faulting address, the virtual address that was
accessed to cause the fault. It may point to code or to
data. It is not necessarily the address of the instruction
that caused the fault (that's f->rip). */
fault_addr = (void *) rcr2();
/* Turn interrupts back on (they were only off so that we could
be assured of reading CR2 before it changed). */
intr_enable ();
/* Determine cause. */
not_present = (f->error_code & PF_P) == 0;
write = (f->error_code & PF_W) != 0;
user = (f->error_code & PF_U) != 0;
#ifdef VM
/* For project 3 and later. */
if (vm_try_handle_fault (f, fault_addr, user, write, not_present))
return;
#endif
핸들러쪽에서 처리할게 없음.
매핑 정보는 있지만, 권한에서 문제가 생겨 실패하는 경우 page fault만으로는 정상처리해야하는지, 실패처리해야하는지 구분하기 어렵다. 따라서, 원인을 알려주는 정보가 필요하다.
page_fault에 있는 not_present, write, user를 이용해, vm_try_handle_fault에서 처리해주어야 한다.
예상으로는 아래와 같이 작성하면 되지 않을까?
// 매핑정보는 있지만, 권한이 없다면 프로세스 종료
if (not_present == false) {
thread_exit();
}