fix: invalidate PTEs of evicted pages before eviction occurs to prevent modificationof pages mid-eviction
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user