https://casys-kaist.github.io/pintos-kaist/project3/introduction.html
https://oslab.kaist.ac.kr/pintosslides/

ํ์ฌ PintOS๋ ์คํ์ ํฌ๊ธฐ๊ฐ ๊ณ ์ ๋์ด์๋ค.
์ด ์คํ์ด overflow๊ฐ ๋๊ฒ๋๋ฉด ํด๋น Process๋ฅผ Kill ํ๋๋ฐ,
์ด๋ Stack Access๋ก ๋ณด์ธ๋ค๋ฉด ์คํ์ ๋๋ ค์ฃผ์ด์ผ ํ๋ค.
์ KAIST ์๋ฃ๋ 32๋นํธ๋ผ esp ํฌ์ธํฐ๋ผ๊ณ ๋์์์ผ๋
You will need to be able to obtain the current value of the user program's stack pointer. Within a system call or a page fault generated by a user program, you can retrieve it from the
rspmember of the structintr_framepassed tosyscall_handler()orpage_fault(), respectively.
GitBook์ rsp ํฌ์ธํฐ๊ฐ ์คํ ์์ญ์ ์ ๊ทผ ํ ์ ์๋ ํฌ์ธํฐ๋ผ๊ณ ๋์์๋ค.

Page fault ํธ๋ค๋ฌ ํจ์์ธ vm_try_handle_fault ์ parameter๋ก ๋ค์ด์ค๋ ์ธ์๋ฅผ ๋ณด์.
intr_frame์ *f๋ก ๋ฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.

intr_frame์ ํ์ธํด๋ณด๋ฉด uintptr_t rsp ๊ฐ ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๋ฐ๋ผ์ ๋ค์ vm_try_handle_fault ์์ ๋ณด๋ฉด f->rsp ๋ก rsp ํฌ์ธํฐ์ ์ ๊ทผ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์์๋ผ ์ ์๋ค.
์์์ ๋ณธ intr_frame์ผ๋ก ์ ๊ทผํ๋ f-> rsp๋ USER MODE์์ ์ ๊ทผํ๋ ๊ฒ์ด๊ณ ,
์์คํ
์ฝ์์๋ Page Fault๊ฐ ๋ฐ์ํ ์ ์๋ค.
f->rsp ๋ก ์ ๊ทผ์ Kernel Stack์ ์ ๊ทผํ๋ ๊ฒ์ด ๋์ด ๋ถ๊ฐ๋ฅํ๋ค.
๋ฐ๋ผ์ thread์ #ifdef ๋ถ๋ถ์ *rsp ํฌ์ธํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ ๋ณ์๋ฅผ ๋ฃ์ด์ฃผ์๋ค.

Most Oses impose some absolute limit on stack size. Some OSes make the limit user-adjustable, e.g. with the ulimit command on many Unix systems. On many GNU/Linux systems, the default limit is 8 MB. For this project, you should limit the stack size to be 1MB at maximum.
PintOS์ USER STACK์ ํฌ๊ธฐ๋ 1MB๋ผ๊ณ ํ๋ค.
์ด๋ ์คํ์ TOP์ ๊ฐ๋ฆฌํค๋ rsp๋ณด๋ค ๋ฎ์ ์ฃผ์๋ก ์ ๊ทผํ ๋ ์ด rsp๋ฅผ ์๋๋ก ๋ด๋ ค์
Stack ํ์ฅ์ ํด์ฃผ์ด์ผ ํ๋ค.
๋ฐ๋ผ์ USER_STACK ~ USER_STACK-1MB ์ฌ์ด์ ์ ๊ทผํด์ผํ๋ค.
๋ค๋ง, ์ฌ๊ธฐ์ ์ฃผ์ํ ์ฌํญ์ rsp๋ณด๋ค ๋์ ์ฃผ์๊ฐ์ ์ ๊ทผํ ๊ฒฝ์ฐ์๋ง ์คํํด์ผํ๋ค.
OS๊ฐ ์คํ๋๋ค๊ฐ ํ๋ก์ธ์ค๋ฅผ ์ค๋จ์, ์คํ์ ๋ณด๋ฅผ ์คํ์ ์ ์ฅํ๋ค.
์ด๋ ์คํ ํฌ์ธํฐ ์๋์ ๋ฐ์ดํฐ๋ฅผ ์จ๋์๋ค๋ฉด ๋ฐ์ดํฐ๊ฐ ๋ฎ์ด ์์์ง๋ฉฐ ๋ณ๊ฒฝ๋ ์ ์๋ค.
However, the x86-64 PUSH instruction checks access permissions before it adjusts the stack pointer, so it may cause a page fault 8 bytes below the stack pointer.
๋ฐ๋ผ์ rsp-8 ์ฃผ์์์๋ stack growth๋ฅผ ์ ์ฉํด์ฃผ์ด์ผ ํ๋ค.
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;
void *MAX_STACK = (USER_STACK - (1 << 20));
if (addr == NULL || is_kernel_vaddr(addr))
return false;
if (not_present)
{
/** Project 3-Stack Growth*/
if (page == NULL)
{
// ํ์ด์ง๊ฐ spt์ ์กด์ฌํ์ง ์๋๋ค๋ฉด, ์ฆ ์์ง ํด๋น ๊ฐ์ ์ฃผ์์ ๋ํ ๋งคํ์ด ์๋ค๋ฉด,
void *rsp = user ? pg_round_down(f->rsp) : thread_current()->rsp;
// ๋ง์ฝ ์ ์ ๋ชจ๋๋ผ๋ฉด ์ ์ ์คํ ํฌ์ธํฐ(rsp)๋ฅผ ํ์ฌ ์ธํฐ๋ฝํธ ํ๋ ์์์ ๊ฐ์ ธ์ค๊ณ ,
// ๊ทธ๋ ์ง ์์ผ๋ฉด (์ปค๋ ๋ชจ๋์ผ ๊ฒฝ์ฐ) ํ์ฌ ์ค๋ ๋์ ์ ์ฅํด๋ ์คํ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ๋ค.
// ๋จ, ์ ์ ์คํ์ ํ์ด์ง ๋จ์๋ก ํ ๋น๋๊ธฐ ๋๋ฌธ์ rsp๋ฅผ ํ์ด์ง ํ๋จ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ค.
if (MAX_STACK <= rsp - 8 && rsp - 8 == addr && addr <= USER_STACK)
{
// push ๋ช
๋ น์ด ๋ฑ์ผ๋ก ์ธํด rsp๋ณด๋ค ๋ฎ์ ์ฃผ์์ ์ฐ๊ธฐ๋ฅผ ์๋ํ ๊ฒฝ์ฐ
// ์คํ ํ๋ ์ ํธ์ ์ง์ ์ฃผ์ ์ ๊ทผ์ธ ๊ฒฝ์ฐ (push ๋ช
๋ น์ด ์งํ์ fault ๋๋ ์ํฉ
if (!vm_stack_growth(addr))
return false;
}
else if (MAX_STACK <= rsp && rsp <= addr && addr <= USER_STACK)
{
// rsp๋ณด๋ค ๋์ ์ฃผ์์ ์ ๊ทผํ์ง๋ง ์ฌ์ ํ ์คํ ์์ญ์ธ ๊ฒฝ์ฐ
// ์ผ๋ฐ์ ์ธ ์คํ ์ฌ์ฉ (์: ์ง์ญ ๋ณ์ ํ ๋น ๋ฑ)์ผ๋ก ์ธํ ์ ๊ทผ์ ๊ฒฝ์ฐ
if (!vm_stack_growth(addr))
return false;
}
page = spt_find_page(spt, addr);
}
if (page == NULL || (write && !page->writable))
return false;
return vm_do_claim_page(page);
}
return false;
}
/* Growing the stack. */
static bool
vm_stack_growth(void *addr UNUSED)
{
void *va = pg_round_down(addr);
if (vm_alloc_page_with_initializer(VM_ANON | VM_MARKER_0, va, true, NULL, NULL))
{
thread_current()->rsp = va;
return vm_claim_page(va);
}
return false;
}
pass tests/vm/pt-grow-stack
pass tests/vm/pt-grow-bad
pass tests/vm/pt-big-stk-obj
pass tests/vm/pt-bad-addr
pass tests/vm/pt-bad-read
pass tests/vm/pt-write-code
pass tests/vm/pt-write-code2
pass tests/vm/pt-grow-stk-sc
pass tests/userprog/args-none
pass tests/userprog/args-single
pass tests/userprog/args-multiple
pass tests/userprog/args-many
pass tests/userprog/args-dbl-space
pass tests/userprog/halt
pass tests/userprog/exit
pass tests/userprog/create-normal
pass tests/userprog/create-empty
pass tests/userprog/create-null
pass tests/userprog/create-bad-ptr
pass tests/userprog/create-long
pass tests/userprog/create-exists
pass tests/userprog/create-bound
pass tests/userprog/open-normal
pass tests/userprog/open-missing
pass tests/userprog/open-boundary
pass tests/userprog/open-empty
pass tests/userprog/open-null
pass tests/userprog/open-bad-ptr
pass tests/userprog/open-twice
pass tests/userprog/close-normal
pass tests/userprog/close-twice
pass tests/userprog/close-bad-fd
pass tests/userprog/read-normal
pass tests/userprog/read-bad-ptr
pass tests/userprog/read-boundary
pass tests/userprog/read-zero
pass tests/userprog/read-stdout
pass tests/userprog/read-bad-fd
pass tests/userprog/write-normal
pass tests/userprog/write-bad-ptr
pass tests/userprog/write-boundary
pass tests/userprog/write-zero
pass tests/userprog/write-stdin
pass tests/userprog/write-bad-fd
pass tests/userprog/fork-once
pass tests/userprog/fork-multiple
pass tests/userprog/fork-recursive
FAIL tests/userprog/fork-read
pass tests/userprog/fork-close
pass tests/userprog/fork-boundary
pass tests/userprog/exec-once
pass tests/userprog/exec-arg
FAIL tests/userprog/exec-boundary
pass tests/userprog/exec-missing
pass tests/userprog/exec-bad-ptr
pass tests/userprog/exec-read
pass tests/userprog/wait-simple
pass tests/userprog/wait-twice
pass tests/userprog/wait-killed
pass tests/userprog/wait-bad-pid
pass tests/userprog/multi-recurse
pass tests/userprog/multi-child-fd
pass tests/userprog/rox-simple
pass tests/userprog/rox-child
pass tests/userprog/rox-multichild
pass tests/userprog/bad-read
pass tests/userprog/bad-write
pass tests/userprog/bad-read2
pass tests/userprog/bad-write2
pass tests/userprog/bad-jump
pass tests/userprog/bad-jump2
pass tests/vm/pt-grow-stack
pass tests/vm/pt-grow-bad
pass tests/vm/pt-big-stk-obj
pass tests/vm/pt-bad-addr
pass tests/vm/pt-bad-read
pass tests/vm/pt-write-code
pass tests/vm/pt-write-code2
pass tests/vm/pt-grow-stk-sc
pass tests/vm/page-linear
FAIL tests/vm/page-parallel
pass tests/vm/page-merge-seq
FAIL tests/vm/page-merge-par
FAIL tests/vm/page-merge-stk
FAIL tests/vm/page-merge-mm
pass tests/vm/page-shuffle
FAIL tests/vm/mmap-read
FAIL tests/vm/mmap-close
FAIL tests/vm/mmap-unmap
FAIL tests/vm/mmap-overlap
FAIL tests/vm/mmap-twice
FAIL tests/vm/mmap-write
pass tests/vm/mmap-ro
FAIL tests/vm/mmap-exit
FAIL tests/vm/mmap-shuffle
FAIL tests/vm/mmap-bad-fd
FAIL tests/vm/mmap-clean
FAIL tests/vm/mmap-inherit
FAIL tests/vm/mmap-misalign
FAIL tests/vm/mmap-null
FAIL tests/vm/mmap-over-code
FAIL tests/vm/mmap-over-data
FAIL tests/vm/mmap-over-stk
FAIL tests/vm/mmap-remove
pass tests/vm/mmap-zero
FAIL tests/vm/mmap-bad-fd2
FAIL tests/vm/mmap-bad-fd3
FAIL tests/vm/mmap-zero-len
FAIL tests/vm/mmap-off
FAIL tests/vm/mmap-bad-off
FAIL tests/vm/mmap-kernel
FAIL tests/vm/lazy-file
pass tests/vm/lazy-anon
FAIL tests/vm/swap-file
FAIL tests/vm/swap-anon
FAIL tests/vm/swap-iter
FAIL tests/vm/swap-fork
pass tests/filesys/base/lg-create
pass tests/filesys/base/lg-full
pass tests/filesys/base/lg-random
pass tests/filesys/base/lg-seq-block
pass tests/filesys/base/lg-seq-random
pass tests/filesys/base/sm-create
pass tests/filesys/base/sm-full
pass tests/filesys/base/sm-random
pass tests/filesys/base/sm-seq-block
pass tests/filesys/base/sm-seq-random
FAIL tests/filesys/base/syn-read
pass tests/filesys/base/syn-remove
FAIL tests/filesys/base/syn-write
pass tests/threads/alarm-single
pass tests/threads/alarm-multiple
pass tests/threads/alarm-simultaneous
pass tests/threads/alarm-priority
pass tests/threads/alarm-zero
pass tests/threads/alarm-negative
pass tests/threads/priority-change
FAIL tests/threads/priority-donate-one
pass tests/threads/priority-donate-multiple
pass tests/threads/priority-donate-multiple2
pass tests/threads/priority-donate-nest
pass tests/threads/priority-donate-sema
pass tests/threads/priority-donate-lower
pass tests/threads/priority-fifo
pass tests/threads/priority-preempt
pass tests/threads/priority-sema
pass tests/threads/priority-condvar
pass tests/threads/priority-donate-chain
FAIL tests/vm/cow/cow-simple
38 of 141 tests failed.