diff --git a/src/userprog/pagedir.c b/src/userprog/pagedir.c index f222c18..886bb25 100644 --- a/src/userprog/pagedir.c +++ b/src/userprog/pagedir.c @@ -7,7 +7,6 @@ #include "threads/palloc.h" static uint32_t *active_pd (void); -static void invalidate_pagedir (uint32_t *); /* Creates a new page directory that has mappings for kernel virtual addresses, but none for user virtual addresses. @@ -278,7 +277,7 @@ active_pd (void) This function invalidates the TLB if PD is the active page directory. (If PD is not active then its entries are not in the TLB, so there is no need to invalidate anything.) */ -static void +void invalidate_pagedir (uint32_t *pd) { if (active_pd () == pd) diff --git a/src/userprog/pagedir.h b/src/userprog/pagedir.h index b9ec549..6b8fd26 100644 --- a/src/userprog/pagedir.h +++ b/src/userprog/pagedir.h @@ -17,5 +17,6 @@ void pagedir_set_accessed (uint32_t *pd, const void *upage, bool accessed); bool pagedir_is_writable (uint32_t *pd, const void *upage); void pagedir_set_writable (uint32_t *pd, const void *upage, bool writable); void pagedir_activate (uint32_t *pd); +void invalidate_pagedir (uint32_t *pd); #endif /* userprog/pagedir.h */ diff --git a/src/vm/frame.c b/src/vm/frame.c index cdb141c..0f515ac 100644 --- a/src/vm/frame.c +++ b/src/vm/frame.c @@ -93,6 +93,13 @@ frame_alloc (enum palloc_flags flags, void *upage, struct thread *owner) ASSERT (victim != NULL); /* get_victim () should never return null. */ /* 2. Swap out victim into disk. */ + /* Mark page as 'not present' and flag the page directory as having + been modified *before* eviction begins to prevent the owner of the + victim page from accessing/modifying it mid-eviction. */ + pagedir_clear_page (owner->pagedir, upage); + + // TODO: Lock PTE of victim page for victim process. + size_t swap_slot = swap_out (victim->frame); page_set_swap (victim->owner, victim->upage, swap_slot); diff --git a/src/vm/page.c b/src/vm/page.c index 3b45b14..1f4ef42 100644 --- a/src/vm/page.c +++ b/src/vm/page.c @@ -6,8 +6,8 @@ #define ADDR_START_BIT 12 /* Updates the 'owner' thread's page table entry for virtual address 'upage' - to have a present bit of 0 and stores the specified swap slot value in the - entry for later retrieval from disk. */ + to flag the page as being stored in swap, and stores the specified swap slot + value in the entry at the address bits for later retrieval from disk. */ void page_set_swap (struct thread *owner, void *upage, size_t swap_slot) { @@ -19,9 +19,7 @@ page_set_swap (struct thread *owner, void *upage, size_t swap_slot) uint32_t swap_slot_bits = (swap_slot << ADDR_START_BIT) & PTE_ADDR; *pte = (*pte & PTE_FLAGS) | swap_slot_bits; - /* Mark page as 'not present' and flag the page directory as having - been modified. */ - pagedir_clear_page (owner->pagedir, upage); + invalidate_pagedir (owner->pagedir); } /* Returns true iff the page with user address 'upage' owned by 'owner'