Search

Page Fault

static bool load_segment(struct file *file, off_t ofs, uint8_t *upage, uint32_t read_bytes, uint32_t zero_bytes, bool writable) { ASSERT((read_bytes + zero_bytes) % PGSIZE == 0); ASSERT(pg_ofs(upage) == 0); ASSERT(ofs % PGSIZE == 0); while (read_bytes > 0 || zero_bytes > 0) { /* Do calculate how to fill this page. * We will read PAGE_READ_BYTES bytes from FILE * and zero the final PAGE_ZERO_BYTES bytes. */ size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE; size_t page_zero_bytes = PGSIZE - page_read_bytes; /* TODO: Set up aux to pass information to the lazy_load_segment. */ /* 실제 로딩을 하는건 아니고, 페이지 폴트 발생 시 로딩하도록 페이지만 등록 */ void *aux = NULL; if (!vm_alloc_page_with_initializer(VM_ANON, upage, writable, lazy_load_segment, aux)) return false; /* Advance. */ read_bytes -= page_read_bytes; zero_bytes -= page_zero_bytes; upage += PGSIZE; } return true; }
C
복사
static void 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 /* 최종 코드 결국 페이지 폴트가 발생하는 경우에 exit(-1)을 호출하면 되는거라 일단 원본 유지하고 USERPROG일 때만 호출 될 수 있도록 했습니다!! */ #ifdef USERPROG if (user) { exit(-1); } #endif /* Count page faults. */ page_fault_cnt++; /* If the fault is true fault, show info and exit. */ printf("Page fault at %p: %s error %s page in %s context.\n", fault_addr, not_present ? "not present" : "rights violation", write ? "writing" : "reading", user ? "user" : "kernel"); kill(f); }
C
복사
/* 페이지 폴트 처리 함수 : exception.c 파일에서 호출 * not_present가 true인 경우에만 호출 */ bool vm_try_handle_fault(struct intr_frame *f UNUSED, void *addr UNUSED, bool user UNUSED, bool write UNUSED, bool not_present UNUSED) { struct supplemental_page_table *spt UNUSED = &thread_current()->spt; struct page *page = NULL; /* TODO: Validate the fault */ /* TODO: Your code goes here */ return vm_do_claim_page(page); }
C
복사