mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
vmm: some work towards page locking
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user