Skip to content

Commit

Permalink
better pmm refill implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sparchatus committed Dec 3, 2024
1 parent 682553d commit cd4260c
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 100 deletions.
74 changes: 27 additions & 47 deletions arch/x86/pagetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,11 @@ static inline void clean_pagetable(void *tab) {
set_pgentry(e, MFN_INVALID, PT_NO_FLAGS);
}

static mfn_t get_cr3_mfn(cr3_t *cr3_entry, bool special_path) {
static mfn_t get_cr3_mfn(cr3_t *cr3_entry) {
void *cr3_mapped = NULL;

if (mfn_invalid(cr3_entry->mfn)) {
frame_t *frame;
if (special_path) {
frame = _get_backup_frame();
}
else {
frame = get_backup_frame();
}
frame_t *frame = get_free_frame_norefill();
BUG_ON(!frame);
frame->flags.pagetable = 1;

Expand Down Expand Up @@ -238,8 +232,7 @@ static inline void pgentry_fixup_flags(pgentry_t *entry, unsigned long flags) {
}
}

static mfn_t get_pgentry_mfn(mfn_t tab_mfn, pt_index_t index, unsigned long flags,
bool special_path) {
static mfn_t get_pgentry_mfn(mfn_t tab_mfn, pt_index_t index, unsigned long flags) {
pgentry_t *tab, *entry;
mfn_t mfn;

Expand All @@ -250,13 +243,7 @@ static mfn_t get_pgentry_mfn(mfn_t tab_mfn, pt_index_t index, unsigned long flag

mfn = mfn_from_pgentry(*entry);
if (mfn_invalid(mfn)) {
frame_t *frame;
if (special_path) {
frame = _get_backup_frame();
}
else {
frame = get_backup_frame();
}
frame_t *frame = get_free_frame_norefill();
BUG_ON(!frame);
frame->flags.pagetable = 1;

Expand All @@ -277,21 +264,20 @@ static mfn_t get_pgentry_mfn(mfn_t tab_mfn, pt_index_t index, unsigned long flag
* MAP_FAILED when failed to map a NULL (0x0) virtual address and otherwise
* it returns the same virtual address passed as argument.
*/
void *__vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
static void *_vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
#if defined(__x86_64__)
unsigned long l4_flags,
unsigned long l4_flags,
#endif
unsigned long l3_flags, unsigned long l2_flags, unsigned long l1_flags,
bool special_path) {
unsigned long l3_flags, unsigned long l2_flags,
unsigned long l1_flags) {
mfn_t l1t_mfn, l2t_mfn, l3t_mfn;
pgentry_t *tab, *entry;

if ((_ul(va) & ~PAGE_ORDER_TO_MASK(order)) || !is_canon_va(va))
return va ? NULL : MAP_FAILED;

#if defined(__x86_64__)
l3t_mfn = get_pgentry_mfn(get_cr3_mfn(cr3_ptr, special_path), l4_table_index(va),
l4_flags, special_path);
l3t_mfn = get_pgentry_mfn(get_cr3_mfn(cr3_ptr), l4_table_index(va), l4_flags);
#else
l3t_mfn = get_cr3_mfn(cr3_ptr);
#endif
Expand All @@ -304,7 +290,7 @@ void *__vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
goto done;
}

l2t_mfn = get_pgentry_mfn(l3t_mfn, l3_table_index(va), l3_flags, special_path);
l2t_mfn = get_pgentry_mfn(l3t_mfn, l3_table_index(va), l3_flags);

if (order == PAGE_ORDER_2M) {
tab = tmp_map_mfn(l2t_mfn);
Expand All @@ -314,7 +300,7 @@ void *__vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
goto done;
}

l1t_mfn = get_pgentry_mfn(l2t_mfn, l2_table_index(va), l2_flags, special_path);
l1t_mfn = get_pgentry_mfn(l2t_mfn, l2_table_index(va), l2_flags);

tab = tmp_map_mfn(l1t_mfn);
entry = &tab[l1_table_index(va)];
Expand All @@ -325,28 +311,6 @@ void *__vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
refill_from_paging();
return va;
}
static void *_vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
#if defined(__x86_64__)
unsigned long l4_flags,
#endif
unsigned long l3_flags, unsigned long l2_flags,
unsigned long l1_flags) {
return __vmap(cr3_ptr, va, mfn, order, l4_flags, l3_flags, l2_flags, l1_flags, false);
}
void *__vmap_paging(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
#if defined(__x86_64__)
unsigned long l4_flags,
#endif
unsigned long l3_flags, unsigned long l2_flags,
unsigned long l1_flags, bool special_path, bool take_lock) {
if (take_lock)
spin_lock(&vmap_lock);
void *res = __vmap(cr3_ptr, va, mfn, order, l4_flags, l3_flags, l2_flags, l1_flags,
special_path);
if (take_lock)
spin_unlock(&vmap_lock);
return res;
}

static inline void *__vmap_1g(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned long l4_flags,
unsigned long l3_flags) {
Expand Down Expand Up @@ -457,6 +421,22 @@ void *vmap_4k(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned long l1_flags,
return va;
}

void *vmap_frame_refill(void *va, mfn_t mfn, bool paging_lock) {
unsigned long _va = _ul(va) & PAGE_ORDER_TO_MASK(PAGE_ORDER_4K);

dprintk("%s: va: 0x%p mfn: 0x%lx\n", __func__, va, mfn);

ASSERT(vmap_lock);

if (paging_lock)
spin_lock(&vmap_lock);
va = _vmap_4k(&cr3, _ptr(_va), mfn, L1_PROT, false);
if (paging_lock)
spin_unlock(&vmap_lock);

return va;
}

static inline void init_tmp_mapping(void) {
pte_t *tab = get_l1_table(_tmp_mapping);
_tmp_mapping_entry = (pgentry_t *) l1_table_entry(tab, _tmp_mapping);
Expand Down
9 changes: 2 additions & 7 deletions include/arch/x86/pagetable.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,8 @@ static inline void *vmap_kern_4k(void *va, mfn_t mfn, unsigned long l1_flags) {
return vmap_4k(&cr3, va, mfn, l1_flags, false);
}

void *vmap_frame_refill(void *va, mfn_t mfn, bool paging_lock);

static inline void *vmap_user(void *va, mfn_t mfn, unsigned int order,
#if defined(__x86_64__)
unsigned long l4_flags,
Expand All @@ -386,13 +388,6 @@ static inline void setup_tlb_global(void) {
write_cr4(opt_tlb_global ? (cr4 | X86_CR4_PGE) : (cr4 & ~X86_CR4_PGE));
}

void *__vmap_paging(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
#if defined(__x86_64__)
unsigned long l4_flags,
#endif
unsigned long l3_flags, unsigned long l2_flags,
unsigned long l1_flags, bool special_path, bool paging_lock);

#endif /* __ASSEMBLY__ */

#endif /* KTF_PAGETABLE_H */
3 changes: 1 addition & 2 deletions include/mm/pmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ static inline bool is_frame_free(const frame_t *frame) {
}

void refill_from_paging(void);
frame_t *get_backup_frame(void);
frame_t *_get_backup_frame(void);
frame_t *get_free_frame_norefill(void);

#endif /* __ASSEMBLY__ */

Expand Down
Loading

0 comments on commit cd4260c

Please sign in to comment.