vmm: some work towards page locking

This commit is contained in:
Matheus
2026-02-12 16:25:35 -03:00
parent 3e2a64be5d
commit b3d5bf5586
6 changed files with 56 additions and 7 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ static timekeeper_source_info_t *kvm_timer_init(void) {
int page_offset = (uintptr_t)virtual_address % PAGE_SIZE;
void *virtual_page = (void *)((uintptr_t)virtual_address - page_offset);
void *physical_page = vmm_getphysical(virtual_page, false);
void *physical_page = vmm_getphysical(virtual_page, 0);
__assert(physical_page);
timekeeper_source_info->private = (void *)((uintptr_t)physical_page + page_offset);
+4 -1
View File
@@ -101,7 +101,10 @@ void vmm_unmap(void *addr, size_t size, int flags);
bool vmm_pagefault(void *addr, bool user, int actions);
vmmcontext_t *vmm_newcontext();
void vmm_switchcontext(vmmcontext_t *ctx);
void *vmm_getphysical(void *addr, bool hold);
#define VMM_GET_PHYSICAL_FLAGS_HOLD 1
#define VMM_GET_PHYSICAL_FLAGS_LOCK 2
void *vmm_getphysical(void *addr, int flags);
void vmm_apinit();
void vmm_init();
+2
View File
@@ -24,6 +24,8 @@
#define ARCH_MMU_FLAGS_UC (1 << 4)
#define ARCH_MMU_FLAGS_WC ((1 << 12) | (1 << 3)) // PAT5 (limine sets up the 5th PAT entry as WC)
#define PAGE_MASK 0xfffffffffffff000lu
#define ARCH_MMU_REQUIRED_FLAGS ARCH_MMU_FLAGS_READ
typedef uint64_t mmuflags_t;
+1 -1
View File
@@ -245,7 +245,7 @@ int iovec_iterator_next_page(iovec_iterator_t *iovec_iterator, size_t *page_offs
return 0;
}
void *phys = vmm_getphysical((void *)((uintptr_t)addr - offset_in_page), true);
void *phys = vmm_getphysical((void *)((uintptr_t)addr - offset_in_page), VMM_GET_PHYSICAL_FLAGS_HOLD | VMM_GET_PHYSICAL_FLAGS_LOCK);
if (phys == NULL)
return EFAULT;
+47 -3
View File
@@ -694,7 +694,43 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
return status;
}
void *vmm_getphysical(void *addr, bool hold) {
/*
static int lock_page(vmmspace_t *space, void *vaddr) {
vmmrange_t *range = getrange(space, vaddr);
if (!range)
return ENOENT;
void *mapped_address = arch_mmu_getphysical(current_vmm_context()->pagetable, vaddr);
bool present = arch_mmu_ispresent(current_vmm_context()->pagetable, vaddr);
bool writable = arch_mmu_iswritable(current_vmm_context()->pagetable, vaddr);
bool file_mapping = range->flags & VMM_FLAGS_FILE;
bool private = (range->flags & VMM_FLAGS_SHARED) == 0 || file_mapping == false;
void *real_phys;
// TODO anon with refcount == 1 can go into another cas
// TODO read-only permission checking for DMA
// TODO shared anonymous mappings are not handled properly by the kernel
if (present && writable == false && private)) {
// CoW cases (private mapping)
real_phys = pmm_allocpage(PMM_SECTION_DEFAULT);
if (real_phys == NULL)
return ENOMEM;
memcpy(MAKE_HHDM(real_phys), MAKE_HHDM(mapped_address), PAGE_SIZE);
arch_mmu_remap(current_vmm_context()->pagetable, real_phys, vaddr, range->mmuflags);
arch_mmu_invalidate_range(vaddr, PAGE_SIZE);
if (file_mapping == false || vfs_iscacheable(range->vnode))
pmm_release(mapped_address);
} else if (present == false && private) {
// not present private mapping case
real_phys = pmm_allocpage(PMM_SECTION_DEFAULT);
if (real_phys == NULL)
}
}
*/
void *vmm_getphysical(void *addr, int flags) {
void *aligned_addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
vmmspace_t *space = getspace(aligned_addr);
@@ -703,11 +739,19 @@ void *vmm_getphysical(void *addr, bool hold) {
MUTEX_ACQUIRE(&space->lock);
void *physical = arch_mmu_getphysical(current_vmm_context()->pagetable, aligned_addr);
void *physical;
/*
if ((flags & VMM_GET_PHYSICAL_FLAGS_LOCK) && lock_page(space, aligned_addrr)) {
physical = NULL;
goto leave;
}*/
if (hold)
physical = arch_mmu_getphysical(current_vmm_context()->pagetable, aligned_addr);
if (flags & VMM_GET_PHYSICAL_FLAGS_HOLD)
pmm_hold(physical);
leave:
MUTEX_RELEASE(&space->lock);
return physical + ((uintptr_t)addr - (uintptr_t)aligned_addr);
}
+1 -1
View File
@@ -72,7 +72,7 @@ syscallret_t syscall_futex(context_t *, uint32_t *futexp, int op, uint32_t value
if (unlikely(ret.errno))
goto cleanup;
uint32_t *physical = vmm_getphysical(futexp, false);
uint32_t *physical = vmm_getphysical(futexp, 0);
futex_t *futex = getfutex(physical);
switch (op) {