흐름도

Page Fault가 발생

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

시나리오

시나리오1 (normal access)

핸들러쪽에서 처리할게 없음.

시나리오2

매핑 정보는 있지만, 권한에서 문제가 생겨 실패하는 경우 page fault만으로는 정상처리해야하는지, 실패처리해야하는지 구분하기 어렵다. 따라서, 원인을 알려주는 정보가 필요하다.

page_fault에 있는 not_present, write, user를 이용해, vm_try_handle_fault에서 처리해주어야 한다.

예상으로는 아래와 같이 작성하면 되지 않을까?

// 매핑정보는 있지만, 권한이 없다면 프로세스 종료
if (not_present == false) {
	thread_exit();
}

시나리오3 (lazy loading)

시나리오4

시나리오5

시나리오6

추후 일정