[PINTOS PROJECT 3] VIRTUAL MEMORY_Stack Growth

1800 ワード

1. vm_try_handle_fault()
  • スタックスペースが不足すると、ページ障害が発生し、スタック
  • を拡張する必要がある.
  • ページ障害がスタックスペースが不足しているか無効なアドレスにアクセスしているかを確認する必要があります.
    -->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)スタックを拡張する場合、ページサイズ
    4)展開ページの指定
    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
    }