728x90

➡️ 과제 설명(Gitbook)

 

Stack Growth · GitBook

In project 2, the stack was a single page starting from the USER_STACK, and programs' executions were limited to this size. Now, if the stack grows past its current size, we allocate additional pages as necessary. Allocate additional pages only if they "ap

casys-kaist.github.io

 

  • 기존 스택의 크기는 4KB의 단일 페이지였다.
    But, 이제는 스택이 현재 크기를 초과하면 필요에 따라 추가 페이지를 할당한다.

 

  • 추가 페이지 : 스택에 접근하는 경우에만 할당
    스택에 접근하는 경우와 아닌 경우를 구별하는 휴리스틱(경험적 접근방법)을 만들기

 

  • 유저 프로그램은 스택 포인터 아래의 스택을 쓸 경우 버그가 발생한다.
    • 일반적인 실제 OS가 스택 데이터를 수정하는 신호를 전달하기 위해 프로세스를 언제든지 방해(중단)할 수 있기 때문이다.
  • 그러나 x86-64 PUSH 명령은 스택포인터를 조정하기 전에 접근 권한을 확인하기 때문에 스택포인터 보다 8bytes 아래에 page fault를 발생시킬 수 있다.
  • 유저 프로그램의 스택 포인터의 현재 값을 얻을 수 있어야 한다.
  • 시스템콜이나 유저 프로그램에 의해 발생한 page fault안에서 각각 syscall_handlerpage fault 에 전달된 구조 intr_framersp 멤버에서 검색할 수 있다.
    • 시스템 콜은 syscall_handler 에 전달된 구조 intr_framersp 멤버에 스택 포인터의 값을 확인
    • page fault는 page fault 에 전달된 구조 intr_framersp 멤버에 스택 포인터의 값을 확인
  • 유효하지 않은 메모리 접근을 감지하기 위해 page fault를 의존(사용)하는 경우, 커널에서 발생하는page fault가 발생하는 다른 경우를 처리해야 한다.
  • 예외로 인해 유저모드에서 커널모드로 전활될 때만 프로세서가 스택포인터를 저장하기 때문에 page_fault() 로 전달된 struct intr_frame에서 rsp를 읽으면 사용자 스택 포인터가 아닌 정의되지 않은 값을 얻을 수 있다.
  • 유저에서 커널 모드로 초기 전환시 rsp를 struct thread 에 저장하는 것과 같은 다른 방법을 준비해야 한다.

 

 


Implement stack growth functionalities

  • 구현하기 위해서 vm_try_handle_fault(vm/vm.c)를 수정하여 스택 증가를 확인
  • 스택 증가를 확인한 후, vm_stack_growth(vm/vm.c)를 호출하여 스택을 증가시켜야 한다.
  • vm_stack_growth 를 구현할 것!

 


bool vm_try_handle_fault (struct intr_frame *f, void *addr,
    bool user, bool write, bool not_present);
  • page fault 예외를 처리하는 동안 userprog/exception.c에서 page_fault() 로 호출된다.
  • 이 함수에서는 page fault가 스택을 증가시켜야 하는 경우에 해당하는지 여부를 확인해야 한다.
  • 스택 증가로 page fault를 처리할 수 있다면, page fault가 발생한 주소로 vm_stack_growth 를 호출한다.

 


void vm_stack_growth (void *addr);
  • addr 이 더이상 page fault가 발생하는 주소가 되지 않도록 하나 이상의 익명 페이지를 할당하여 스택의 크기를 증가시킨다.
  • ⭐ 페이지를 할당할 때는 주소를 PGSIZE 기준으로 내림하기

 

  • 대부분의 OS는 스택 크기가 절대적으로 제한되어 있다.
    이번 프로젝트에서 스택의 크기를 최대 1MB로 제한해야 한다.
    일부 OS는 사용자가 크기 제한을 조정할 수 있게 한다. GNU/리눅스 시스템에서 기본 제한은 8MB이다.

 

  • 모든 stack-growth 테스트를 통과해야 한다.

 

 

728x90

'🌱 Dev Diary > 📄 TIL' 카테고리의 다른 글

Project 3. Memory Mapped Files  (0) 2023.01.19
Project 3. Stack Growth(2)  (0) 2023.01.19
Project 3. Anonymous Page(2)  (0) 2023.01.19
Project 3. Anonymous Page(1)  (0) 2023.01.19
Project 3. Memory Management  (0) 2023.01.19