mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 06:58: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;
|
int page_offset = (uintptr_t)virtual_address % PAGE_SIZE;
|
||||||
void *virtual_page = (void *)((uintptr_t)virtual_address - page_offset);
|
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);
|
__assert(physical_page);
|
||||||
|
|
||||||
timekeeper_source_info->private = (void *)((uintptr_t)physical_page + page_offset);
|
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);
|
bool vmm_pagefault(void *addr, bool user, int actions);
|
||||||
vmmcontext_t *vmm_newcontext();
|
vmmcontext_t *vmm_newcontext();
|
||||||
void vmm_switchcontext(vmmcontext_t *ctx);
|
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_apinit();
|
||||||
void vmm_init();
|
void vmm_init();
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#define ARCH_MMU_FLAGS_UC (1 << 4)
|
#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 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
|
#define ARCH_MMU_REQUIRED_FLAGS ARCH_MMU_FLAGS_READ
|
||||||
|
|
||||||
typedef uint64_t mmuflags_t;
|
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;
|
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)
|
if (phys == NULL)
|
||||||
return EFAULT;
|
return EFAULT;
|
||||||
|
|
||||||
|
|||||||
+47
-3
@@ -694,7 +694,43 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
|||||||
return status;
|
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);
|
void *aligned_addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
|
||||||
|
|
||||||
vmmspace_t *space = getspace(aligned_addr);
|
vmmspace_t *space = getspace(aligned_addr);
|
||||||
@@ -703,11 +739,19 @@ void *vmm_getphysical(void *addr, bool hold) {
|
|||||||
|
|
||||||
MUTEX_ACQUIRE(&space->lock);
|
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);
|
pmm_hold(physical);
|
||||||
|
|
||||||
|
leave:
|
||||||
MUTEX_RELEASE(&space->lock);
|
MUTEX_RELEASE(&space->lock);
|
||||||
return physical + ((uintptr_t)addr - (uintptr_t)aligned_addr);
|
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))
|
if (unlikely(ret.errno))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
uint32_t *physical = vmm_getphysical(futexp, false);
|
uint32_t *physical = vmm_getphysical(futexp, 0);
|
||||||
futex_t *futex = getfutex(physical);
|
futex_t *futex = getfutex(physical);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|||||||
Reference in New Issue
Block a user