[PINTOS PROJECT 3] VIRTUAL MEMORY_Stack Growth

zeo·2021년 10월 29일
0

1. vm_try_handle_fault()

  • stack에 공간이 부족한 경우, page fault가 발생하게 되므로 stack 확장 필요
  • 또한, page fault가 발생한 이유가 stack 공간이 부족해서 인지 유효하지 않은 주소에 접근한 것인지 확인 필요
    --> 이를 위해 page fault 발생 전의 user stack pointer 위치 저장 필요
bool
vm_try_handle_fault (struct intr_frame *f UNUSED, void *addr,
		bool user, bool write, bool not_present) {
	struct thread *curr = thread_current ();
	struct supplemental_page_table *spt = &curr->spt;
	/* Validate the fault */
	if (is_kernel_vaddr (addr) && user) return false;
	void *stack_bottom = pg_round_down (curr->rsp);
	if (write && (stack_bottom - PGSIZE <= addr &&
	      (uintptr_t) addr < USER_STACK)) {
	  /* Allow stack growth writing below single PGSIZE range
	   * of current stack bottom inferred from stack pointer. */
	  vm_stack_growth (addr);
	  return true;
	}
	struct page* page = spt_find_page (spt, addr);
	if (page == NULL) return false;
	if (write && !not_present) return vm_handle_wp (page);
	return vm_do_claim_page (page);
}

2. vm_stack_growth()

1) stack_bottom 설정
2) 확장 요청한 스택 사이즈 확인
3) 스택 확장시, page 크기 단위로 해주기
4) 확장한 page 할당받기

static void
vm_stack_growth (void *addr UNUSED) {
	void *stack_bottom = pg_round_down (addr);
	size_t req_stack_size = USER_STACK - (uintptr_t)stack_bottom;
	if (req_stack_size > (1 << 20)) PANIC("Stack limit exceeded!\n"); // 최대 1MB

	// Alloc page from tested region to previous claimed stack page.
	void *growing_stack_bottom = stack_bottom;
	while ((uintptr_t) growing_stack_bottom < USER_STACK && 
		vm_alloc_page (VM_ANON | VM_MARKER_0, growing_stack_bottom, true)) {
	      growing_stack_bottom += PGSIZE;
	};
	vm_claim_page (stack_bottom); // Lazy load requested stack page only
}

0개의 댓글