fix: invalidate PTEs of evicted pages before eviction occurs to prevent modificationof pages mid-eviction

This commit is contained in:
Themis Demetriades
2024-12-04 15:02:49 +00:00
parent 47a7dfae04
commit 1b73e415d7
4 changed files with 12 additions and 7 deletions

View File

@@ -7,7 +7,6 @@
#include "threads/palloc.h" #include "threads/palloc.h"
static uint32_t *active_pd (void); static uint32_t *active_pd (void);
static void invalidate_pagedir (uint32_t *);
/* Creates a new page directory that has mappings for kernel /* Creates a new page directory that has mappings for kernel
virtual addresses, but none for user virtual addresses. 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 This function invalidates the TLB if PD is the active page
directory. (If PD is not active then its entries are not in directory. (If PD is not active then its entries are not in
the TLB, so there is no need to invalidate anything.) */ the TLB, so there is no need to invalidate anything.) */
static void void
invalidate_pagedir (uint32_t *pd) invalidate_pagedir (uint32_t *pd)
{ {
if (active_pd () == pd) if (active_pd () == pd)

View File

@@ -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); bool pagedir_is_writable (uint32_t *pd, const void *upage);
void pagedir_set_writable (uint32_t *pd, const void *upage, bool writable); void pagedir_set_writable (uint32_t *pd, const void *upage, bool writable);
void pagedir_activate (uint32_t *pd); void pagedir_activate (uint32_t *pd);
void invalidate_pagedir (uint32_t *pd);
#endif /* userprog/pagedir.h */ #endif /* userprog/pagedir.h */

View File

@@ -93,6 +93,13 @@ frame_alloc (enum palloc_flags flags, void *upage, struct thread *owner)
ASSERT (victim != NULL); /* get_victim () should never return null. */ ASSERT (victim != NULL); /* get_victim () should never return null. */
/* 2. Swap out victim into disk. */ /* 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); size_t swap_slot = swap_out (victim->frame);
page_set_swap (victim->owner, victim->upage, swap_slot); page_set_swap (victim->owner, victim->upage, swap_slot);

View File

@@ -6,8 +6,8 @@
#define ADDR_START_BIT 12 #define ADDR_START_BIT 12
/* Updates the 'owner' thread's page table entry for virtual address 'upage' /* 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 to flag the page as being stored in swap, and stores the specified swap slot
entry for later retrieval from disk. */ value in the entry at the address bits for later retrieval from disk. */
void void
page_set_swap (struct thread *owner, void *upage, size_t swap_slot) 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; uint32_t swap_slot_bits = (swap_slot << ADDR_START_BIT) & PTE_ADDR;
*pte = (*pte & PTE_FLAGS) | swap_slot_bits; *pte = (*pte & PTE_FLAGS) | swap_slot_bits;
/* Mark page as 'not present' and flag the page directory as having invalidate_pagedir (owner->pagedir);
been modified. */
pagedir_clear_page (owner->pagedir, upage);
} }
/* Returns true iff the page with user address 'upage' owned by 'owner' /* Returns true iff the page with user address 'upage' owned by 'owner'