From 8a81340b78def3895c119d5ada63cbe3a8452985 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 24 Apr 2025 12:38:28 -0400 Subject: const pointers on free & kmapuseraddr --- kernel/memory/paging.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 4f1b788..f286027 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -5,6 +5,7 @@ #include "physalloc.h" #include "paging.h" #include "memory.h" +#include // PAGE MAP LEVEL 4 ENTRY struct pml4e { @@ -214,7 +215,7 @@ static volatile struct pt *pt_map(volatile struct pt *pPT) // locate a pdpt for a vitural address // @returns PHYSICAL ADDRESS static volatile struct pdpt *pdpt_locate(volatile struct pml4 *pPML4, - void *vADDR) + const void *vADDR) { volatile struct pml4 *vPML4; volatile struct pml4e *vPML4E; @@ -235,7 +236,7 @@ static volatile struct pdpt *pdpt_locate(volatile struct pml4 *pPML4, // locate a pd for a vitural address // @returns PHYSICAL ADDRESS -static volatile struct pd *pd_locate(volatile struct pdpt *pPDPT, void *vADDR) +static volatile struct pd *pd_locate(volatile struct pdpt *pPDPT, const void *vADDR) { volatile struct pdpt *vPDPT; volatile struct pdpte *vPDPTE; @@ -256,7 +257,7 @@ static volatile struct pd *pd_locate(volatile struct pdpt *pPDPT, void *vADDR) // locate a pt for a vitural address // @returns PHYSICAL ADDRESS -static volatile struct pt *pt_locate(volatile struct pd *pPD, void *vADDR) +static volatile struct pt *pt_locate(volatile struct pd *pPD, const void *vADDR) { volatile struct pd *vPD; volatile struct pde *vPDE; @@ -506,7 +507,7 @@ free: // locate a pte for a vitural address // @returns VIRTUAL ADDRESS static volatile struct pte *page_locate(volatile struct pml4 *pPML4, - void *vADDR) + const void *vADDR) { volatile struct pdpt *pPDPT; volatile struct pd *pPD; @@ -573,7 +574,7 @@ static volatile struct pte *page_alloc(volatile struct pml4 *pPML4, void *vADDR, } // free a pte (page) for a vitural address -static void page_free(volatile struct pml4 *pPML4, void *vADDR) +static void page_free(volatile struct pml4 *pPML4, const void *vADDR) { volatile struct pte *vPTE; void *pADDR; @@ -591,7 +592,7 @@ static void page_free(volatile struct pml4 *pPML4, void *vADDR) /* map & unmap pages */ -static void unmap_pages(volatile struct pml4 *pPML4, void *vADDR, +static void unmap_pages(volatile struct pml4 *pPML4, const void *vADDR, long page_count) { for (long i = 0; i < page_count; i++) { @@ -717,7 +718,22 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, return (char *)virt + error; } -void mem_unmapaddr(mem_ctx_t ctx, void *virt) +void *kmapuseraddr(mem_ctx_t ctx, const void *vADDR, size_t len) +{ + char *pADDR; + volatile struct pte *vPTE; + + vPTE = page_locate((volatile struct pml4 *)ctx->pml4, vADDR); + if (vPTE == NULL) + return NULL; + + pADDR = (void *)((uintptr_t)vPTE->address << 12); + pADDR += ((uint64_t)vADDR % PAGE_SIZE); + + return kmapaddr(pADDR, NULL, len, F_PRESENT | F_WRITEABLE); +} + +void mem_unmapaddr(mem_ctx_t ctx, const void *virt) { if (virt == NULL) return; @@ -768,7 +784,7 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, return virt; } -void mem_free_pages(mem_ctx_t ctx, void *virt) +void mem_free_pages(mem_ctx_t ctx, const void *virt) { if (virt == NULL) return; -- cgit v1.2.3-freya From f5c474cf77965376614e8c42a48f1f295228bcd6 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 24 Apr 2025 13:41:38 -0400 Subject: fmt --- kernel/cpu/tss.c | 14 ++++++++------ kernel/lib/backtrace.c | 4 +++- kernel/memory/paging.c | 6 +++--- kernel/syscall.c | 28 +++++++++------------------- 4 files changed, 23 insertions(+), 29 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/cpu/tss.c b/kernel/cpu/tss.c index bda713b..100525b 100644 --- a/kernel/cpu/tss.c +++ b/kernel/cpu/tss.c @@ -11,7 +11,7 @@ struct sys_seg_descriptor { uint64_t : 1; uint64_t DPL : 2; uint64_t present : 1; - uint64_t limit16_19: 4; + uint64_t limit16_19 : 4; uint64_t available : 1; uint64_t : 1; uint64_t : 1; @@ -49,16 +49,17 @@ static volatile struct sys_seg_descriptor *GDT_TSS; // kernel stack pointer extern char kern_stack_end[]; -void tss_init(void) { - uint64_t base = (uint64_t) &tss; +void tss_init(void) +{ + uint64_t base = (uint64_t)&tss; uint64_t limit = sizeof tss - 1; // setup tss entry memsetv(&tss, 0, sizeof(struct tss)); - tss.rsp0 = (uint64_t) kern_stack_end; + tss.rsp0 = (uint64_t)kern_stack_end; // map tss into gdt - GDT_TSS = (volatile struct sys_seg_descriptor *) (GDT + 0x28); + GDT_TSS = (volatile struct sys_seg_descriptor *)(GDT + 0x28); memsetv(GDT_TSS, 0, sizeof(struct sys_seg_descriptor)); GDT_TSS->limit0_15 = limit & 0xFFFF; GDT_TSS->base0_15 = base & 0xFFFF; @@ -75,6 +76,7 @@ void tss_init(void) { tss_flush(); } -void tss_set_stack(uint64_t stack) { +void tss_set_stack(uint64_t stack) +{ tss.rsp0 = stack; } diff --git a/kernel/lib/backtrace.c b/kernel/lib/backtrace.c index 102e775..2507be4 100644 --- a/kernel/lib/backtrace.c +++ b/kernel/lib/backtrace.c @@ -9,7 +9,9 @@ struct stackframe { extern char kern_stack_start[]; extern char kern_stack_end[]; -#define VALID(frame) (frame && (char*)(frame) >= kern_stack_start && ((char*)(frame) <= kern_stack_end)) +#define VALID(frame) \ + (frame && (char *)(frame) >= kern_stack_start && \ + ((char *)(frame) <= kern_stack_end)) size_t backtrace(void **dst, size_t len) { diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index f286027..80ab833 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -236,7 +236,8 @@ static volatile struct pdpt *pdpt_locate(volatile struct pml4 *pPML4, // locate a pd for a vitural address // @returns PHYSICAL ADDRESS -static volatile struct pd *pd_locate(volatile struct pdpt *pPDPT, const void *vADDR) +static volatile struct pd *pd_locate(volatile struct pdpt *pPDPT, + const void *vADDR) { volatile struct pdpt *vPDPT; volatile struct pdpte *vPDPTE; @@ -667,8 +668,7 @@ volatile void *paging_alloc(void) if (pPML4 == NULL) return NULL; - if (map_pages(pPML4, kernel_start, kernel_start, - F_PRESENT | F_WRITEABLE, + if (map_pages(pPML4, kernel_start, kernel_start, F_PRESENT | F_WRITEABLE, (kernel_end - kernel_start) / PAGE_SIZE)) { pml4_free(pPML4, false); return NULL; diff --git a/kernel/syscall.c b/kernel/syscall.c index 7887e83..7944f46 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -12,7 +12,7 @@ static int sys_exit(void) { ARG1(int, status); - (void) status; + (void)status; // FIXME: schedule somthing else while (1) @@ -53,23 +53,12 @@ static int sys_write(void) } static int (*syscall_tbl[N_SYSCALLS])(void) = { - [SYS_exit] = sys_exit, - [SYS_waitpid] = NULL, - [SYS_fork] = NULL, - [SYS_exec] = NULL, - [SYS_open] = NULL, - [SYS_close] = NULL, - [SYS_read] = NULL, - [SYS_write] = sys_write, - [SYS_getpid] = NULL, - [SYS_getppid] = NULL, - [SYS_gettime] = NULL, - [SYS_getprio] = NULL, - [SYS_setprio] = NULL, - [SYS_kill] = NULL, - [SYS_sleep] = NULL, - [SYS_brk] = NULL, - [SYS_sbrk] = NULL, + [SYS_exit] = sys_exit, [SYS_waitpid] = NULL, [SYS_fork] = NULL, + [SYS_exec] = NULL, [SYS_open] = NULL, [SYS_close] = NULL, + [SYS_read] = NULL, [SYS_write] = sys_write, [SYS_getpid] = NULL, + [SYS_getppid] = NULL, [SYS_gettime] = NULL, [SYS_getprio] = NULL, + [SYS_setprio] = NULL, [SYS_kill] = NULL, [SYS_sleep] = NULL, + [SYS_brk] = NULL, [SYS_sbrk] = NULL, }; void syscall_handler(struct cpu_regs *regs) @@ -91,7 +80,8 @@ void syscall_handler(struct cpu_regs *regs) if (num >= N_SYSCALLS) { // invalid syscall // FIXME: kill user process - while(1); + while (1) + ; } // run syscall handler (if exists) -- cgit v1.2.3-freya From 0096743bce5e1e3e03756fd4f7c441036e1589cd Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 24 Apr 2025 14:37:44 -0400 Subject: fix paging free fns --- kernel/memory/paging.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 80ab833..58c5091 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -416,6 +416,13 @@ static void pt_free(volatile struct pt *pPT, bool force) pADDR = (void *)((uintptr_t)vPTE->address << 12); free_phys_page(pADDR); + count--; + } + + if (!force && count) { + vPT->count_low = count; + vPT->count_high = count >> 2; + return; } free: @@ -443,6 +450,12 @@ static void pd_free(volatile struct pd *pPD, bool force) pPT = (volatile struct pt *)((uintptr_t)vPDE->address << 12); pt_free(pPT, force); + count--; + } + + if (!force && count) { + vPD->count = count; + return; } free: @@ -470,6 +483,12 @@ static void pdpt_free(volatile struct pdpt *pPDPT, bool force) pPD = (volatile struct pd *)((uintptr_t)vPDPTE->address << 12); pd_free(pPD, force); + count--; + } + + if (!force && count) { + vPDPT->count = count; + return; } free: @@ -497,6 +516,12 @@ static void pml4_free(volatile struct pml4 *pPML4, bool force) pPDPT = (volatile struct pdpt *)((uintptr_t)vPML4E->address << 12); pdpt_free(pPDPT, force); + count--; + } + + if (!force && count) { + vPML4->count = count; + return; } free: -- cgit v1.2.3-freya From 3c213ce446c6547c79f683f035b191e92b4e914e Mon Sep 17 00:00:00 2001 From: Ian McFarlane Date: Thu, 24 Apr 2025 15:50:50 -0400 Subject: make alloc_pages_at() able to allocate noncontiguous physical pages --- kernel/include/lib.h | 1 + kernel/include/lib/kmath.h | 20 ++++++++++++++++++ kernel/memory/paging.c | 36 +++++++++++++++++++++++++------- kernel/memory/physalloc.c | 52 +++++++++++++++++++++++++++++++++++++++++----- kernel/memory/physalloc.h | 33 ++++++++++++++++++++++++++--- 5 files changed, 126 insertions(+), 16 deletions(-) create mode 100644 kernel/include/lib/kmath.h (limited to 'kernel/memory/paging.c') diff --git a/kernel/include/lib.h b/kernel/include/lib.h index be4e739..edfbeb4 100644 --- a/kernel/include/lib.h +++ b/kernel/include/lib.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #endif /* lib.h */ diff --git a/kernel/include/lib/kmath.h b/kernel/include/lib/kmath.h new file mode 100644 index 0000000..3be953d --- /dev/null +++ b/kernel/include/lib/kmath.h @@ -0,0 +1,20 @@ +/** + * @file kmath.h + * + * @author Ian McFarlane + * + * Kernel math functions + */ + +#ifndef _KMATH_H +#define _KMATH_H + +#include + +// min and max both prefer a over b +#define MAX(a, b) ((a) >= (b) ? (a) : (b)) +#define MIN(a, b) ((a) <= (b) ? (a) : (b)) + +#define CLAMP(val, min, max) (MAX((min), MIN((val), (max)))) + +#endif diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 58c5091..24a9ea7 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -796,16 +796,36 @@ void *mem_alloc_pages(mem_ctx_t ctx, size_t count, unsigned int flags) void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, unsigned int flags) { - void *phys = alloc_phys_pages(count); - if (phys == NULL) - return NULL; + size_t pages_needed = count; + uint8_t *virtual_address = virt; + + void *phys_start = NULL; + + while (pages_needed > 0) { + struct phys_page_slice phys_pages = + alloc_phys_page_withextra(pages_needed); + if (phys_pages.pagestart == NULL) { + free_phys_pages(phys_start ? phys_start : phys_pages.pagestart, + count - pages_needed); + return NULL; + } - if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, - count)) { - if (phys) - free_phys_pages(phys, count); - return NULL; + if (!phys_start) + phys_start = phys_pages.pagestart; + + assert(pages_needed >= phys_pages.num_pages, "overflow"); + pages_needed -= phys_pages.num_pages; + virtual_address += phys_pages.num_pages * PAGE_SIZE; + + if (map_pages((volatile struct pml4 *)ctx->pml4, + (void *)virtual_address, phys_pages.pagestart, flags, + phys_pages.num_pages)) { + assert(phys_start, "expected something allocated"); + free_phys_pages(phys_start, count - pages_needed); + return NULL; + } } + return virt; } diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 60e7017..856a627 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -58,7 +58,7 @@ static long page_idx(void *page) return -1; } -static inline bool bitmap_get(int i) +static inline bool bitmap_get(size_t i) { return (bitmap[i / 64] >> i % 64) & 1; } @@ -76,17 +76,17 @@ static inline void bitmap_set(int i, bool v) void *alloc_phys_page(void) { - return alloc_phys_pages(1); + return alloc_phys_pages_exact(1); } -void *alloc_phys_pages(size_t pages) +void *alloc_phys_pages_exact(size_t pages) { if (pages < 1) return NULL; size_t n_contiguous = 0; - int free_region_start = 0; - for (uint64_t i = 0; i < page_count; i++) { + size_t free_region_start = 0; + for (size_t i = 0; i < page_count; i++) { bool free = !bitmap_get(i); if (free) { @@ -105,11 +105,53 @@ void *alloc_phys_pages(size_t pages) return NULL; } +struct phys_page_slice alloc_phys_page_withextra(size_t max_pages) +{ + if (max_pages == 0) + return PHYS_PAGE_SLICE_NULL; + + for (size_t i = 0; i < page_count; i++) { + const bool free = !bitmap_get(i); + if (!free) + continue; + + // now allocated + bitmap_set(i, true); + + // found at least one page, guaranteed to return valid slice at this + // point + struct phys_page_slice out = { + .pagestart = page_at(i), + .num_pages = 1, + }; + + // add some extra pages if possible + for (; out.num_pages < MIN(page_count - i, max_pages); + ++out.num_pages) { + // early return if max_pages isn't available + if (bitmap_get(i + out.num_pages)) { + return out; + } + bitmap_set(i + out.num_pages, true); + } + + return out; + } + + // only reachable if there is not a single free page in the bitmap + return PHYS_PAGE_SLICE_NULL; +} + void free_phys_page(void *ptr) { free_phys_pages(ptr, 1); } +void free_phys_pages_slice(struct phys_page_slice slice) +{ + free_phys_pages(slice.pagestart, slice.num_pages); +} + void free_phys_pages(void *ptr, size_t pages) { if (ptr == NULL) diff --git a/kernel/memory/physalloc.h b/kernel/memory/physalloc.h index d91c57a..e279409 100644 --- a/kernel/memory/physalloc.h +++ b/kernel/memory/physalloc.h @@ -11,11 +11,31 @@ #include +/// Represents some contiguous physical pages +struct phys_page_slice { + void *pagestart; + size_t num_pages; +}; + +#define PHYS_PAGE_SLICE_NULL \ + ((struct phys_page_slice){ .pagestart = NULL, .num_pages = 0 }) + /** * Initalize the physical page allocator */ void physalloc_init(struct memory_map *map); +/* + * Allocates the first page(s) it finds. Returns a pointer to that page + * and, if there are (up to max_pages) extra pages free after it, it allocates + * them as well. + * + * @param max_pages - the maximum number of pages to mark as allocated + * @returns a slice of all of the allocated pages, num_pages will be + * <= max_pages + */ +struct phys_page_slice alloc_phys_page_withextra(size_t max_pages); + /** * Allocates a single physical page in memory * @preturns the physical address of the page @@ -23,10 +43,11 @@ void physalloc_init(struct memory_map *map); void *alloc_phys_page(void); /** - * Allocates count physical pages in memory - * @returns the physical address of the first page + * Allocates count contiguous physical pages in memory + * @returns the physical address of the first page, or NULL if no + * contiguous pages exist. */ -void *alloc_phys_pages(size_t count); +void *alloc_phys_pages_exact(size_t count); /** * Frees a single physical page in memory @@ -41,4 +62,10 @@ void free_phys_page(void *ptr); */ void free_phys_pages(void *ptr, size_t count); +/** + * Frees a slice of physical pages in memory + * @param slice - the pages to free + */ +void free_phys_pages_slice(struct phys_page_slice slice); + #endif /* physalloc.h */ -- cgit v1.2.3-freya From b39f0b08ca73f9059402a0bc869244b384cebd5c Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 25 Apr 2025 10:03:30 -0400 Subject: pgdir clone stub, constify free fns --- kernel/include/comus/memory.h | 2 +- kernel/memory/memory.c | 26 ++++++++++++++++++++------ kernel/memory/paging.c | 25 ++++++++++++++++--------- kernel/memory/paging.h | 7 +++++-- 4 files changed, 42 insertions(+), 18 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/include/comus/memory.h b/kernel/include/comus/memory.h index 255eca2..92525da 100644 --- a/kernel/include/comus/memory.h +++ b/kernel/include/comus/memory.h @@ -87,7 +87,7 @@ mem_ctx_t mem_ctx_alloc(void); * * @returns pointer context or NULL on failure */ -mem_ctx_t mem_ctx_clone(mem_ctx_t ctx, bool cow); +mem_ctx_t mem_ctx_clone(const mem_ctx_t ctx, bool cow); /** * Free a memory context into a new one diff --git a/kernel/memory/memory.c b/kernel/memory/memory.c index 7ceb491..295823e 100644 --- a/kernel/memory/memory.c +++ b/kernel/memory/memory.c @@ -52,7 +52,7 @@ mem_ctx_t mem_ctx_alloc(void) if (ctx == NULL) return NULL; - if ((ctx->pml4 = paging_alloc()) == NULL) + if ((ctx->pml4 = pgdir_alloc()) == NULL) return NULL; virtaddr_init(&ctx->virtctx); @@ -64,17 +64,31 @@ mem_ctx_t mem_ctx_alloc(void) return ctx; } -mem_ctx_t mem_ctx_clone(mem_ctx_t ctx, bool cow) +mem_ctx_t mem_ctx_clone(const mem_ctx_t old, bool cow) { - (void)ctx; - (void)cow; + mem_ctx_t new = user_mem_ctx_next; + if (new == NULL) + return NULL; + + if ((new->pml4 = pgdir_clone(old->pml4, cow)) == NULL) + return NULL; + + if (virtaddr_clone(&old->virtctx, &new->virtctx)) { + pgdir_free(new->pml4); + return NULL; + } + + user_mem_ctx_next = new->prev; + if (new->prev) + new->prev->next = NULL; + new->prev = NULL; - panic("not yet implemented"); + return new; } void mem_ctx_free(mem_ctx_t ctx) { - paging_free(ctx->pml4); + pgdir_free(ctx->pml4); virtaddr_cleanup(&ctx->virtctx); if (user_mem_ctx_next == NULL) { diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 24a9ea7..c6e6a82 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -5,7 +5,6 @@ #include "physalloc.h" #include "paging.h" #include "memory.h" -#include // PAGE MAP LEVEL 4 ENTRY struct pml4e { @@ -139,7 +138,7 @@ extern char kernel_start[]; extern char kernel_end[]; // invalidate page cache at a vitural address -static inline void invlpg(volatile void *vADDR) +static inline void invlpg(volatile const void *vADDR) { __asm__ volatile("invlpg (%0)" ::"r"(vADDR) : "memory"); } @@ -150,7 +149,7 @@ static inline void invlpg(volatile void *vADDR) // @returns VIRTUAL ADDRESS static volatile struct pml4 *pml4_map(volatile struct pml4 *pPML4) { - static struct pml4 *vPML4 = (void *)(uintptr_t)0x40000000; + static volatile struct pml4 *vPML4 = (void *)(uintptr_t)0x40000000; static volatile struct pte *vPTE = &paging_pt.entries[0]; if ((uint64_t)pPML4 >> 12 == vPTE->address) @@ -166,7 +165,7 @@ static volatile struct pml4 *pml4_map(volatile struct pml4 *pPML4) // @returns VIRTUAL ADDRESS static volatile struct pdpt *pdpt_map(volatile struct pdpt *pPDPT) { - static struct pdpt *vPDPT = (void *)(uintptr_t)0x40001000; + static volatile struct pdpt *vPDPT = (void *)(uintptr_t)0x40001000; static volatile struct pte *vPTE = &paging_pt.entries[1]; if ((uint64_t)pPDPT >> 12 == vPTE->address) @@ -182,7 +181,7 @@ static volatile struct pdpt *pdpt_map(volatile struct pdpt *pPDPT) // @returns VIRTUAL ADDRESS static volatile struct pd *pd_map(volatile struct pd *pPD) { - static struct pd *vPD = (void *)(uintptr_t)0x40002000; + static volatile struct pd *vPD = (void *)(uintptr_t)0x40002000; static volatile struct pte *vPTE = &paging_pt.entries[2]; if ((uint64_t)pPD >> 12 == vPTE->address) @@ -198,7 +197,7 @@ static volatile struct pd *pd_map(volatile struct pd *pPD) // @returns VIRTUAL ADDRESS static volatile struct pt *pt_map(volatile struct pt *pPT) { - static struct pt *vPT = (void *)(uintptr_t)0x40003000; + static volatile struct pt *vPT = (void *)(uintptr_t)0x40003000; static volatile struct pte *vPTE = &paging_pt.entries[3]; if ((uint64_t)pPT >> 12 == vPTE->address) @@ -678,14 +677,14 @@ void paging_init(void) kernel_pd_1.entries[0].flags = F_PRESENT | F_WRITEABLE; kernel_pd_1.entries[0].address = (uint64_t)(paging_pt.entries) >> 12; - memsetv(paging_pt.entries, 0, 4096); + memsetv(paging_pt.entries, 0, PAGE_SIZE); // make sure we are using THESE pagetables // EFI doesnt on boot __asm__ volatile("mov %0, %%cr3" ::"r"(kernel_pml4.entries) : "memory"); } -volatile void *paging_alloc(void) +volatile void *pgdir_alloc(void) { volatile struct pml4 *pPML4; @@ -702,7 +701,15 @@ volatile void *paging_alloc(void) return pPML4; } -void paging_free(volatile void *addr) +volatile void *pgdir_clone(volatile const void *old_pgdir, bool cow) +{ + // TODO: + (void) old_pgdir; + (void) cow; + return NULL; +} + +void pgdir_free(volatile void *addr) { pml4_free(addr, true); } diff --git a/kernel/memory/paging.h b/kernel/memory/paging.h index d80a9bf..94b7260 100644 --- a/kernel/memory/paging.h +++ b/kernel/memory/paging.h @@ -9,9 +9,12 @@ #ifndef PAGING_H_ #define PAGING_H_ +#include + void paging_init(void); -volatile void *paging_alloc(void); -void paging_free(volatile void *addr); +volatile void *pgdir_alloc(void); +volatile void *pgdir_clone(volatile const void *pdir, bool cow); +void pgdir_free(volatile void *addr); #endif /* paging.h */ -- cgit v1.2.3-freya From 1f89036816a1a3d45e62b101a9cff873ac41dfbc Mon Sep 17 00:00:00 2001 From: Ian McFarlane Date: Fri, 25 Apr 2025 10:24:35 -0400 Subject: fix freeing of virtual memory --- kernel/memory/paging.c | 57 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 17 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index c6e6a82..8de1a24 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -804,36 +804,59 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, unsigned int flags) { size_t pages_needed = count; - uint8_t *virtual_address = virt; - void *phys_start = NULL; + struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; + struct phys_page_slice phys_pages; while (pages_needed > 0) { - struct phys_page_slice phys_pages = - alloc_phys_page_withextra(pages_needed); + phys_pages = alloc_phys_page_withextra(pages_needed); if (phys_pages.pagestart == NULL) { - free_phys_pages(phys_start ? phys_start : phys_pages.pagestart, - count - pages_needed); - return NULL; + goto mem_alloc_pages_at_fail; } - if (!phys_start) - phys_start = phys_pages.pagestart; + { + // allocate the first page and store in it the physical address of the + // previous chunk of pages + // TODO: skip this if there are already enough pages from first alloc + void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, + F_PRESENT | F_WRITEABLE); + if (pageone == NULL) { + panic("kernel out of virtual memory"); + } + *((struct phys_page_slice *)pageone) = prev_phys_block; + prev_phys_block = phys_pages; + kunmapaddr(pageone); + } assert(pages_needed >= phys_pages.num_pages, "overflow"); pages_needed -= phys_pages.num_pages; - virtual_address += phys_pages.num_pages * PAGE_SIZE; - - if (map_pages((volatile struct pml4 *)ctx->pml4, - (void *)virtual_address, phys_pages.pagestart, flags, - phys_pages.num_pages)) { - assert(phys_start, "expected something allocated"); - free_phys_pages(phys_start, count - pages_needed); - return NULL; + + // index into virtual page array at index [count - pages_needed] + void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); + if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, + phys_pages.pagestart, flags, phys_pages.num_pages)) { + goto mem_alloc_pages_at_fail; } } return virt; + +mem_alloc_pages_at_fail: + while (prev_phys_block.pagestart) { + void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, + F_PRESENT | F_WRITEABLE); + if (!virtpage) { + // memory corruption, most likely a bug + // could also ERROR here and exit with leak + panic("unable to free memory from failed mem_alloc_pages_at call"); + } + struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; + prev_phys_block = prev; + free_phys_pages_slice(prev); + kunmapaddr(virtpage); + } + + return NULL; } void mem_free_pages(mem_ctx_t ctx, const void *virt) -- cgit v1.2.3-freya From 53c7f83e611d6b249097dcae1f748fc2fcc42173 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 25 Apr 2025 11:22:24 -0400 Subject: fmt --- kernel/include/comus/cpu.h | 3 +-- kernel/include/comus/procs.h | 3 +-- kernel/memory/paging.c | 6 +++--- kernel/memory/physalloc.c | 2 +- kernel/memory/virtalloc.c | 12 ++++++++---- kernel/procs.c | 3 +-- 6 files changed, 15 insertions(+), 14 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/include/comus/cpu.h b/kernel/include/comus/cpu.h index 8f485be..3669000 100644 --- a/kernel/include/comus/cpu.h +++ b/kernel/include/comus/cpu.h @@ -92,7 +92,6 @@ void cpu_print_regs(struct cpu_regs *regs); /** * Return from a syscall handler back into userspace */ -__attribute__((noreturn)) -void syscall_return(void); +__attribute__((noreturn)) void syscall_return(void); #endif /* cpu.h */ diff --git a/kernel/include/comus/procs.h b/kernel/include/comus/procs.h index de65849..0150975 100644 --- a/kernel/include/comus/procs.h +++ b/kernel/include/comus/procs.h @@ -222,7 +222,6 @@ void schedule(struct pcb *pcb); /** * Select the next process to receive the CPU */ -__attribute__((noreturn)) -void dispatch(void); +__attribute__((noreturn)) void dispatch(void); #endif /* procs.h */ diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index c6e6a82..3453636 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -704,8 +704,8 @@ volatile void *pgdir_alloc(void) volatile void *pgdir_clone(volatile const void *old_pgdir, bool cow) { // TODO: - (void) old_pgdir; - (void) cow; + (void)old_pgdir; + (void)cow; return NULL; } @@ -827,7 +827,7 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, if (map_pages((volatile struct pml4 *)ctx->pml4, (void *)virtual_address, phys_pages.pagestart, flags, phys_pages.num_pages)) { - assert(phys_start, "expected something allocated"); + assert(phys_start, "expected something allocated"); free_phys_pages(phys_start, count - pages_needed); return NULL; } diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 833c995..9fcbe8f 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -87,7 +87,7 @@ void *alloc_phys_pages_exact(size_t pages) if (bitmap == NULL || page_start == NULL) { // temporary bump allocator - void *addr = (void*)memory_start; + void *addr = (void *)memory_start; memory_start += PAGE_SIZE; return addr; } diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c index 08a0758..cbde9b4 100644 --- a/kernel/memory/virtalloc.c +++ b/kernel/memory/virtalloc.c @@ -102,12 +102,14 @@ int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new) memcpy(new, old, sizeof(struct virt_ctx)); // allocate new space - new->alloc_nodes = kalloc(sizeof(struct virt_addr_node) * new->alloc_node_count); + new->alloc_nodes = + kalloc(sizeof(struct virt_addr_node) * new->alloc_node_count); if (new->alloc_nodes == NULL) return 1; // update prev/next in new allocation space - update_node_ptrs(old->alloc_nodes, new->alloc_nodes, old->alloc_node_count, new->alloc_node_count); + update_node_ptrs(old->alloc_nodes, new->alloc_nodes, old->alloc_node_count, + new->alloc_node_count); // update bootstrap nodes for (size_t i = 0; i < new->used_node_count; i++) { @@ -117,8 +119,10 @@ int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new) break; // get prev - prev = i > 0 ? &new->bootstrap_nodes[i-1] : NULL; - next = i < BOOTSTRAP_VIRT_ALLOC_NODES - 1 ? &new->bootstrap_nodes[i+1] : NULL; + prev = i > 0 ? &new->bootstrap_nodes[i - 1] : NULL; + next = i < BOOTSTRAP_VIRT_ALLOC_NODES - 1 ? + &new->bootstrap_nodes[i + 1] : + NULL; new->bootstrap_nodes[i].prev = prev; new->bootstrap_nodes[i].next = next; diff --git a/kernel/procs.c b/kernel/procs.c index f114f52..340739d 100644 --- a/kernel/procs.c +++ b/kernel/procs.c @@ -461,8 +461,7 @@ void schedule(struct pcb *pcb) panic("schedule insert fail"); } -__attribute__((noreturn)) -void dispatch(void) +__attribute__((noreturn)) void dispatch(void) { assert(current_pcb == NULL, "dispatch: current process is not null"); -- cgit v1.2.3-freya From f88e7fada2f9998063d1816d4375ee7c8735f57f Mon Sep 17 00:00:00 2001 From: Ian McFarlane Date: Fri, 25 Apr 2025 12:15:41 -0400 Subject: fixed segfault caused by mapping the wrong virtual address in mem_alloc_pages_at --- kernel/memory/paging.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index b23e39b..5a0b285 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -828,11 +828,12 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, kunmapaddr(pageone); } + // index into virtual page array at index [count - pages_needed] + void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); + assert(pages_needed >= phys_pages.num_pages, "overflow"); pages_needed -= phys_pages.num_pages; - // index into virtual page array at index [count - pages_needed] - void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, phys_pages.pagestart, flags, phys_pages.num_pages)) { goto mem_alloc_pages_at_fail; -- cgit v1.2.3-freya From 2cf6fe3f4d0811f1d62ed3ba73d15c8a187f600f Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 25 Apr 2025 18:42:30 -0400 Subject: mem_get_phys fn --- kernel/include/comus/memory.h | 13 +++++++++++++ kernel/memory/memory.c | 5 +++++ kernel/memory/paging.c | 23 +++++++++++++++++------ kernel/memory/physalloc.c | 3 ++- 4 files changed, 37 insertions(+), 7 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/include/comus/memory.h b/kernel/include/comus/memory.h index 92525da..408521b 100644 --- a/kernel/include/comus/memory.h +++ b/kernel/include/comus/memory.h @@ -123,6 +123,13 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, */ void mem_unmapaddr(mem_ctx_t ctx, const void *virt); +/** + * Gets the physical address for a given vitural address + * @param ctx - the memory context + * @param virt - the vitural address + */ +void *mem_get_phys(mem_ctx_t ctx, const void *virt); + /** * Allocate a single page of memory with the given paging structure * @@ -194,6 +201,12 @@ void *kmapaddr(void *phys, void *virt, size_t len, unsigned int flags); */ void *kmapuseraddr(mem_ctx_t ctx, const void *virt, size_t len); +/** + * Gets the physical address for a given vitural address + * @param virt - the vitural address + */ +void *kget_phys(const void *virt); + /** * Unmaps mapped address from the kmapaddr function * @param virt - the vitural address returned from kmapaddr diff --git a/kernel/memory/memory.c b/kernel/memory/memory.c index 295823e..bd3e06b 100644 --- a/kernel/memory/memory.c +++ b/kernel/memory/memory.c @@ -31,6 +31,11 @@ void kunmapaddr(const void *virt) mem_unmapaddr(kernel_mem_ctx, virt); } +void *kget_phys(const void *virt) +{ + return mem_get_phys(kernel_mem_ctx, virt); +} + void *kalloc_page(void) { return mem_alloc_page(kernel_mem_ctx, F_PRESENT | F_WRITEABLE); diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 5a0b285..d54a26b 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -5,6 +5,7 @@ #include "physalloc.h" #include "paging.h" #include "memory.h" +#include // PAGE MAP LEVEL 4 ENTRY struct pml4e { @@ -753,15 +754,11 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, void *kmapuseraddr(mem_ctx_t ctx, const void *vADDR, size_t len) { char *pADDR; - volatile struct pte *vPTE; - vPTE = page_locate((volatile struct pml4 *)ctx->pml4, vADDR); - if (vPTE == NULL) + pADDR = mem_get_phys(ctx, vADDR); + if (pADDR == NULL) return NULL; - pADDR = (void *)((uintptr_t)vPTE->address << 12); - pADDR += ((uint64_t)vADDR % PAGE_SIZE); - return kmapaddr(pADDR, NULL, len, F_PRESENT | F_WRITEABLE); } @@ -776,6 +773,20 @@ void mem_unmapaddr(mem_ctx_t ctx, const void *virt) unmap_pages(&kernel_pml4, virt, pages); } +void *mem_get_phys(mem_ctx_t ctx, const void *vADDR) +{ + char *pADDR; + volatile struct pte *vPTE; + + vPTE = page_locate((volatile struct pml4 *)ctx->pml4, vADDR); + if (vPTE == NULL) + return NULL; + + pADDR = (void *)((uintptr_t)vPTE->address << 12); + pADDR += ((uint64_t)vADDR % PAGE_SIZE); + return pADDR; +} + void *mem_alloc_page(mem_ctx_t ctx, unsigned int flags) { return mem_alloc_pages(ctx, 1, flags); diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 01464ee..48d2e3f 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -88,7 +88,8 @@ void *alloc_phys_pages_exact(size_t pages) if (bitmap == NULL || page_start == NULL) { // temporary bump allocator void *addr = (void *)memory_start; - assert(pages == 1, "caller expects more pages, but is only getting one"); + assert(pages == 1, + "caller expects more pages, but is only getting one"); memory_start += PAGE_SIZE; return addr; } -- cgit v1.2.3-freya From bec577fb669910091f09719b5bb6829b963c50c6 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Sun, 27 Apr 2025 14:07:11 -0400 Subject: fix pgdir free, fix mapadder fns --- kernel/memory/paging.c | 82 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 27 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index d54a26b..2cc5b7e 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -600,7 +600,8 @@ static volatile struct pte *page_alloc(volatile struct pml4 *pPML4, void *vADDR, } // free a pte (page) for a vitural address -static void page_free(volatile struct pml4 *pPML4, const void *vADDR) +static void page_free(volatile struct pml4 *pPML4, const void *vADDR, + bool deallocate) { volatile struct pte *vPTE; void *pADDR; @@ -612,17 +613,19 @@ static void page_free(volatile struct pml4 *pPML4, const void *vADDR) vPTE->flags = 0; vPTE->address = 0; - pADDR = (void *)((uintptr_t)vPTE->address << 12); - free_phys_page(pADDR); + if (deallocate) { + pADDR = (void *)((uintptr_t)vPTE->address << 12); + free_phys_page(pADDR); + } } /* map & unmap pages */ static void unmap_pages(volatile struct pml4 *pPML4, const void *vADDR, - long page_count) + long page_count, bool deallocate) { for (long i = 0; i < page_count; i++) { - page_free(pPML4, vADDR); + page_free(pPML4, vADDR, deallocate); vADDR = (char *)vADDR + PAGE_SIZE; } } @@ -644,7 +647,7 @@ static int map_pages(volatile struct pml4 *pPML4, void *vADDR, void *pADDR, return 0; fail: - unmap_pages(pPML4, vADDR, page_count); + unmap_pages(pPML4, vADDR, page_count, true); return 1; } @@ -715,26 +718,17 @@ void pgdir_free(volatile void *addr) pml4_free(addr, true); } -static inline void *page_align(void *addr) -{ - uintptr_t a = (uintptr_t)addr; - a /= PAGE_SIZE; - a *= PAGE_SIZE; - return (void *)a; -} - void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, unsigned int flags) { long pages; - ptrdiff_t error; + size_t error; void *aligned_phys; - // get length and physical page aligned address - aligned_phys = page_align(phys); - error = (char *)phys - (char *)aligned_phys; + error = (size_t)phys % PAGE_SIZE; len += error; - pages = len / PAGE_SIZE + 1; + pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; + aligned_phys = (char *)phys - error; // get page aligned (or allocate) vitural address if (virt == NULL) @@ -742,6 +736,9 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, if (virt == NULL) return NULL; + assert((uint64_t)virt % PAGE_SIZE == 0, + "mem_mapaddr: vitural address not page aligned"); + if (map_pages((volatile struct pml4 *)ctx->pml4, virt, aligned_phys, F_PRESENT | flags, pages)) { virtaddr_free(&ctx->virtctx, virt); @@ -751,26 +748,57 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, return (char *)virt + error; } -void *kmapuseraddr(mem_ctx_t ctx, const void *vADDR, size_t len) +void *kmapuseraddr(mem_ctx_t ctx, const void *usrADDR, size_t len) { - char *pADDR; + volatile struct pml4 *pml4; + char *pADDR, *vADDR; + size_t npages, error, i; - pADDR = mem_get_phys(ctx, vADDR); - if (pADDR == NULL) + pml4 = (volatile struct pml4 *)kernel_mem_ctx->pml4; + npages = (len + PAGE_SIZE - 1) / PAGE_SIZE; + error = (size_t)usrADDR % PAGE_SIZE; + vADDR = virtaddr_alloc(&kernel_mem_ctx->virtctx, npages); + if (vADDR == NULL) return NULL; - return kmapaddr(pADDR, NULL, len, F_PRESENT | F_WRITEABLE); + assert((size_t)vADDR % PAGE_SIZE == 0, + "kmapuseraddr: vitural address not page aligned"); + + for (i = 0; i < npages; i++) { + pADDR = mem_get_phys(ctx, (char *)usrADDR + i * PAGE_SIZE); + if (pADDR == NULL) + goto fail; + + // page align + pADDR = (char *)(((size_t)pADDR / PAGE_SIZE) * PAGE_SIZE); + + if (map_pages(pml4, vADDR + i * PAGE_SIZE, pADDR, + F_PRESENT | F_WRITEABLE, 1)) + goto fail; + } + + return vADDR + error; + +fail: + unmap_pages(&kernel_pml4, vADDR, i, false); + virtaddr_free(&kernel_mem_ctx->virtctx, vADDR); + return NULL; } void mem_unmapaddr(mem_ctx_t ctx, const void *virt) { + long pages; + if (virt == NULL) return; - long pages = virtaddr_free(&ctx->virtctx, virt); + // page align + virt = (void *)(((size_t)virt / PAGE_SIZE) * PAGE_SIZE); + + pages = virtaddr_free(&ctx->virtctx, virt); if (pages < 1) return; - unmap_pages(&kernel_pml4, virt, pages); + unmap_pages(&kernel_pml4, virt, pages, false); } void *mem_get_phys(mem_ctx_t ctx, const void *vADDR) @@ -877,5 +905,5 @@ void mem_free_pages(mem_ctx_t ctx, const void *virt) return; long pages = virtaddr_free(&ctx->virtctx, virt); - unmap_pages((volatile struct pml4 *)ctx->pml4, virt, pages); + unmap_pages((volatile struct pml4 *)ctx->pml4, virt, pages, true); } -- cgit v1.2.3-freya From f894f09bd84c13fb104d3720ead627728f04d6c6 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Mon, 28 Apr 2025 13:05:14 -0400 Subject: allocate vaddrs when given directly --- kernel/memory/paging.c | 9 ++++++ kernel/memory/virtalloc.c | 80 ++++++++++++++++++++++++++++++++++------------- kernel/memory/virtalloc.h | 8 +++++ 3 files changed, 76 insertions(+), 21 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 2cc5b7e..ec3c5c7 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -736,6 +736,9 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, if (virt == NULL) return NULL; + if (virtaddr_take(&ctx->virtctx, virt, pages)) + return NULL; + assert((uint64_t)virt % PAGE_SIZE == 0, "mem_mapaddr: vitural address not page aligned"); @@ -761,6 +764,9 @@ void *kmapuseraddr(mem_ctx_t ctx, const void *usrADDR, size_t len) if (vADDR == NULL) return NULL; + if (virtaddr_take(&kernel_mem_ctx->virtctx, vADDR, npages)) + return NULL; + assert((size_t)vADDR % PAGE_SIZE == 0, "kmapuseraddr: vitural address not page aligned"); @@ -847,6 +853,9 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; struct phys_page_slice phys_pages; + if (virtaddr_take(&ctx->virtctx, virt, count)) + return NULL; + while (pages_needed > 0) { phys_pages = alloc_phys_page_withextra(pages_needed); if (phys_pages.pagestart == NULL) { diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c index cbde9b4..863959e 100644 --- a/kernel/memory/virtalloc.c +++ b/kernel/memory/virtalloc.c @@ -1,5 +1,7 @@ +#include "lib/kio.h" #include #include +#include #include "virtalloc.h" @@ -177,32 +179,68 @@ void *virtaddr_alloc(struct virt_ctx *ctx, int n_pages) if (node->is_alloc) continue; - if (length >= n_length) { - struct virt_addr_node *new = get_node(ctx); - if (node->prev != NULL) { - node->prev->next = new; - } else { - ctx->start_node = new; - } - new->next = node; - new->prev = node->prev; - node->prev = new; - new->start = node->start; - new->end = new->start + n_length; - node->start = new->end; - new->is_alloc = true; - new->is_used = true; - new->next = node; - void *mem = (void *)new->start; - merge_back(ctx, new); - merge_forward(ctx, new); - return mem; - } + if (length < n_length) + continue; + + return (void*)node->start; } return NULL; } +int virtaddr_take(struct virt_ctx *ctx, const void *virt, int n_pages) +{ + if (n_pages < 1) + return 0; + + long n_length = n_pages * PAGE_SIZE; + struct virt_addr_node *node = ctx->start_node; + + for (; node != NULL; node = node->next) { + if (node->is_alloc) + continue; + + if (node->start > (uintptr_t)virt || + node->end < (uintptr_t)virt + n_length) + continue; + + // create new node on left + if (node->start < (uintptr_t) virt) { + struct virt_addr_node *left = get_node(ctx); + left->next = node; + left->prev = node->prev; + left->start = node->start; + left->end = (uintptr_t) virt; + left->is_used = true; + left->is_alloc = false; + node->prev->next = left; + node->prev = left; + } + + // create new node on right + if (node->end > (uintptr_t) virt + n_length) { + struct virt_addr_node *right = get_node(ctx); + right->prev = node; + right->next = node->next; + right->start = (uintptr_t) virt + n_length; + right->end = node->end; + right->is_used = true; + right->is_alloc = false; + node->next->prev = right; + node->next = right; + } + + node->start = (uintptr_t) virt; + node->end = node->start + n_length; + node->is_alloc = true; + node->is_used = true; + + return 0; + } + + return 1; +} + long virtaddr_free(struct virt_ctx *ctx, const void *virtaddr) { if (virtaddr == NULL) diff --git a/kernel/memory/virtalloc.h b/kernel/memory/virtalloc.h index 9a94208..5033242 100644 --- a/kernel/memory/virtalloc.h +++ b/kernel/memory/virtalloc.h @@ -64,6 +64,14 @@ int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new); */ void *virtaddr_alloc(struct virt_ctx *ctx, int pages); +/** + * Take (yoink) a predefined virtual address of length x pages + * @param virt - the start of the vitural address to take + * @param pages - x pages + * @returns 0 on success, 1 on err + */ +int virtaddr_take(struct virt_ctx *ctx, const void *virt, int pages); + /** * Free the virtual address from virtaddr_alloc * @param virtaddr - the addr to free -- cgit v1.2.3-freya From 91baa1659fa523da9b95d426137d32f5aeebc0cd Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Mon, 28 Apr 2025 16:00:53 -0400 Subject: fix pml4 free and physalloc_free --- kernel/memory/paging.c | 8 ++++---- kernel/memory/physalloc.c | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index ec3c5c7..0571148 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -411,7 +411,7 @@ static void pt_free(volatile struct pt *pPT, bool force) void *pADDR; vPTE = &vPT->entries[i]; - if (!force && !(vPTE->flags & F_PRESENT)) + if (!(vPTE->flags & F_PRESENT)) continue; pADDR = (void *)((uintptr_t)vPTE->address << 12); @@ -445,7 +445,7 @@ static void pd_free(volatile struct pd *pPD, bool force) volatile struct pt *pPT; vPDE = &vPD->entries[i]; - if (!force && !(vPDE->flags & F_PRESENT)) + if (!(vPDE->flags & F_PRESENT)) continue; pPT = (volatile struct pt *)((uintptr_t)vPDE->address << 12); @@ -478,7 +478,7 @@ static void pdpt_free(volatile struct pdpt *pPDPT, bool force) volatile struct pd *pPD; vPDPTE = &vPDPT->entries[i]; - if (!force && !(vPDPTE->flags & F_PRESENT)) + if (!(vPDPTE->flags & F_PRESENT)) continue; pPD = (volatile struct pd *)((uintptr_t)vPDPTE->address << 12); @@ -511,7 +511,7 @@ static void pml4_free(volatile struct pml4 *pPML4, bool force) volatile struct pdpt *pPDPT; vPML4E = &vPML4->entries[i]; - if (!force && !(vPML4E->flags & F_PRESENT)) + if (!(vPML4E->flags & F_PRESENT)) continue; pPDPT = (volatile struct pdpt *)((uintptr_t)vPML4E->address << 12); diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index c5a74b7..f47f875 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -4,9 +4,8 @@ #include "physalloc.h" -extern char kernel_start; -extern char kernel_end; -#define kaddr(addr) ((uintptr_t)(&addr)) +extern char kernel_start[]; +extern char kernel_end[]; // between memory_start and kernel_start will be the bitmap static uintptr_t memory_start = 0; @@ -50,6 +49,9 @@ static long page_idx(void *page) int cur_page = 0; for (uint64_t idx = 0; idx < segment_count; idx++) { const struct memory_segment *m = page_start; + if (addr < m->addr) { + return -1; + } if ((uintptr_t)m + m->len > addr) { return cur_page + ((addr - m->addr) / PAGE_SIZE); } @@ -63,7 +65,7 @@ static inline bool bitmap_get(size_t i) return (bitmap[i / 64] >> i % 64) & 1; } -static inline void bitmap_set(int i, bool v) +static inline void bitmap_set(size_t i, bool v) { if (v) free_memory -= PAGE_SIZE; @@ -180,11 +182,11 @@ static bool segment_invalid(const struct memory_segment *segment) return true; if (segment->type != SEG_TYPE_FREE) return true; - if (segment->addr < kaddr(kernel_start)) + if (segment->addr < (uintptr_t) kernel_start) return true; if (segment->addr + segment->len < memory_start) return true; - if (segment->addr + segment->len < kaddr(kernel_start)) + if (segment->addr + segment->len < (uintptr_t) kernel_start) return true; return false; } @@ -198,7 +200,7 @@ static struct memory_segment clamp_segment(const struct memory_segment *segment) if (memory_start) start = memory_start; else - start = kaddr(kernel_end); + start = (uintptr_t) kernel_end; if (segment->addr < start) { addr = start; @@ -243,7 +245,7 @@ void physalloc_init(struct memory_map *map) long bitmap_pages = (page_count / 64 / PAGE_SIZE) + 1; long bitmap_size = bitmap_pages * PAGE_SIZE; - bitmap = (uint64_t *)page_align(kaddr(kernel_end)); + bitmap = (uint64_t *)page_align((uintptr_t)kernel_end); long page_area_size = segment_count * sizeof(struct memory_segment); char *page_area_addr = (char *)bitmap + bitmap_size; -- cgit v1.2.3-freya From 74517ed402d318fee911f9701396fee648887165 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Mon, 28 Apr 2025 17:06:57 -0400 Subject: clone pgdir --- kernel/memory/paging.c | 323 ++++++++++++++++++++++++++++++++++++---------- kernel/memory/physalloc.c | 6 +- kernel/procs.c | 1 + 3 files changed, 257 insertions(+), 73 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 0571148..b089895 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -146,69 +146,41 @@ static inline void invlpg(volatile const void *vADDR) /* map */ -// map a physical pml4 address to access +// map a physical address to a virtural address // @returns VIRTUAL ADDRESS -static volatile struct pml4 *pml4_map(volatile struct pml4 *pPML4) +static volatile void *map_addr(volatile const void *pADDR, size_t pt_idx) { - static volatile struct pml4 *vPML4 = (void *)(uintptr_t)0x40000000; - static volatile struct pte *vPTE = &paging_pt.entries[0]; + volatile char *vADDR; + volatile struct pte *vPTE; - if ((uint64_t)pPML4 >> 12 == vPTE->address) - return vPML4; + assert(pt_idx < 512, "invalid page table entry index"); - vPTE->address = (uint64_t)pPML4 >> 12; - vPTE->flags = F_PRESENT | F_WRITEABLE; - invlpg(vPML4); - return vPML4; -} + vADDR = (char *)(uintptr_t)(0x40000000 + pt_idx * PAGE_SIZE); + vPTE = &paging_pt.entries[pt_idx]; -// map a physical pdpt address to access -// @returns VIRTUAL ADDRESS -static volatile struct pdpt *pdpt_map(volatile struct pdpt *pPDPT) -{ - static volatile struct pdpt *vPDPT = (void *)(uintptr_t)0x40001000; - static volatile struct pte *vPTE = &paging_pt.entries[1]; - - if ((uint64_t)pPDPT >> 12 == vPTE->address) - return vPDPT; + if ((uint64_t)pADDR >> 12 == vPTE->address) + return vADDR; - vPTE->address = (uint64_t)pPDPT >> 12; + vPTE->address = (uint64_t)pADDR >> 12; vPTE->flags = F_PRESENT | F_WRITEABLE; - invlpg(vPDPT); - return vPDPT; + invlpg(vADDR); + return vADDR; } -// map a physical pd address to access -// @returns VIRTUAL ADDRESS -static volatile struct pd *pd_map(volatile struct pd *pPD) -{ - static volatile struct pd *vPD = (void *)(uintptr_t)0x40002000; - static volatile struct pte *vPTE = &paging_pt.entries[2]; - - if ((uint64_t)pPD >> 12 == vPTE->address) - return vPD; +#define PML4_MAP(pADDR) (volatile struct pml4 *)map_addr(pADDR, 0) +#define PML4_MAPC(pADDR) (volatile const struct pml4 *)map_addr(pADDR, 4) - vPTE->address = (uint64_t)pPD >> 12; - vPTE->flags = F_PRESENT | F_WRITEABLE; - invlpg(vPD); - return vPD; -} +#define PDPT_MAP(pADDR) (volatile struct pdpt *)map_addr(pADDR, 1) +#define PDPT_MAPC(pADDR) (volatile const struct pdpt *)map_addr(pADDR, 5) -// map a physical pt address to access -// @returns VIRTUAL ADDRESS -static volatile struct pt *pt_map(volatile struct pt *pPT) -{ - static volatile struct pt *vPT = (void *)(uintptr_t)0x40003000; - static volatile struct pte *vPTE = &paging_pt.entries[3]; +#define PD_MAP(pADDR) (volatile struct pd *)map_addr(pADDR, 2) +#define PD_MAPC(pADDR) (volatile const struct pd *)map_addr(pADDR, 6) - if ((uint64_t)pPT >> 12 == vPTE->address) - return vPT; +#define PT_MAP(pADDR) (volatile struct pt *)map_addr(pADDR, 3) +#define PT_MAPC(pADDR) (volatile const struct pt *)map_addr(pADDR, 7) - vPTE->address = (uint64_t)pPT >> 12; - vPTE->flags = F_PRESENT | F_WRITEABLE; - invlpg(vPT); - return vPT; -} +#define PAGE_MAP(pADDR) (volatile void *)map_addr(pADDR, 8) +#define PAGE_MAPC(pADDR) (volatile const void *)map_addr(pADDR, 9) /* locate */ @@ -223,7 +195,7 @@ static volatile struct pdpt *pdpt_locate(volatile struct pml4 *pPML4, uint64_t offset; offset = (uint64_t)vADDR >> 39; - vPML4 = pml4_map(pPML4); + vPML4 = PML4_MAP(pPML4); vPML4E = &vPML4->entries[offset]; if (vPML4E->flags & F_PRESENT) { @@ -245,7 +217,7 @@ static volatile struct pd *pd_locate(volatile struct pdpt *pPDPT, uint64_t offset; offset = ((uint64_t)vADDR >> 30) & 0x1ff; - vPDPT = pdpt_map(pPDPT); + vPDPT = PDPT_MAP(pPDPT); vPDPTE = &vPDPT->entries[offset]; if (vPDPTE->flags & F_PRESENT) { @@ -266,7 +238,7 @@ static volatile struct pt *pt_locate(volatile struct pd *pPD, const void *vADDR) uint64_t offset; offset = ((uint64_t)vADDR >> 21) & 0x1ff; - vPD = pd_map(pPD); + vPD = PD_MAP(pPD); vPDE = &vPD->entries[offset]; if (vPDE->flags & F_PRESENT) { @@ -289,7 +261,7 @@ static volatile struct pml4 *pml4_alloc(void) if (pPML4 == NULL) return NULL; - vPML4 = pml4_map(pPML4); + vPML4 = PML4_MAP(pPML4); memsetv(vPML4, 0, sizeof(struct pml4)); return pPML4; } @@ -305,7 +277,7 @@ static volatile struct pdpt *pdpt_alloc(volatile struct pml4 *pPML4, uint64_t offset; offset = (uint64_t)vADDR >> 39; - vPML4 = pml4_map(pPML4); + vPML4 = PML4_MAP(pPML4); vPML4E = &vPML4->entries[offset]; pPDPT = pdpt_locate(pPML4, vADDR); @@ -318,7 +290,7 @@ static volatile struct pdpt *pdpt_alloc(volatile struct pml4 *pPML4, if (pPML4 == NULL) return NULL; - vPDPT = pdpt_map(pPDPT); + vPDPT = PDPT_MAP(pPDPT); memsetv(vPDPT, 0, sizeof(struct pdpt)); vPML4E->address = (uintptr_t)pPDPT >> 12; vPML4E->flags = F_PRESENT | flags; @@ -338,7 +310,7 @@ static volatile struct pd *pd_alloc(volatile struct pdpt *pPDPT, void *vADDR, uint64_t offset; offset = ((uint64_t)vADDR >> 30) & 0x1ff; - vPDPT = pdpt_map(pPDPT); + vPDPT = PDPT_MAP(pPDPT); vPDPTE = &vPDPT->entries[offset]; pPD = pd_locate(pPDPT, vADDR); @@ -351,7 +323,7 @@ static volatile struct pd *pd_alloc(volatile struct pdpt *pPDPT, void *vADDR, if (pPDPT == NULL) return NULL; - vPD = pd_map(pPD); + vPD = PD_MAP(pPD); memsetv(vPD, 0, sizeof(struct pd)); vPDPTE->address = (uintptr_t)pPD >> 12; vPDPTE->flags = F_PRESENT | flags; @@ -371,7 +343,7 @@ static volatile struct pt *pt_alloc(volatile struct pd *pPD, void *vADDR, uint64_t offset; offset = ((uint64_t)vADDR >> 21) & 0x1ff; - vPD = pd_map(pPD); + vPD = PD_MAP(pPD); vPDE = &vPD->entries[offset]; pPT = pt_locate(pPD, vADDR); @@ -384,7 +356,7 @@ static volatile struct pt *pt_alloc(volatile struct pd *pPD, void *vADDR, if (pPD == NULL) return NULL; - vPT = pt_map(pPT); + vPT = PT_MAP(pPT); memsetv(vPT, 0, sizeof(struct pt)); vPDE->address = (uintptr_t)pPT >> 12; vPDE->flags = F_PRESENT | flags; @@ -400,7 +372,7 @@ static void pt_free(volatile struct pt *pPT, bool force) volatile struct pt *vPT; uint64_t count; - vPT = pt_map(pPT); + vPT = PT_MAP(pPT); count = (vPT->count_high << 2) | vPT->count_low; if (!count) @@ -434,7 +406,7 @@ static void pd_free(volatile struct pd *pPD, bool force) volatile struct pd *vPD; uint64_t count; - vPD = pd_map(pPD); + vPD = PD_MAP(pPD); count = vPD->count; if (!count) @@ -467,7 +439,7 @@ static void pdpt_free(volatile struct pdpt *pPDPT, bool force) volatile struct pdpt *vPDPT; uint64_t count; - vPDPT = pdpt_map(pPDPT); + vPDPT = PDPT_MAP(pPDPT); count = vPDPT->count; if (!count) @@ -500,7 +472,7 @@ static void pml4_free(volatile struct pml4 *pPML4, bool force) volatile struct pml4 *vPML4; uint64_t count; - vPML4 = pml4_map(pPML4); + vPML4 = PML4_MAP(pPML4); count = vPML4->count; if (!count) @@ -528,6 +500,220 @@ free: free_phys_page((void *)(uintptr_t)pPML4); } +/* clone */ + +volatile void *page_clone(volatile void *old_pADDR, bool cow) +{ + volatile const void *old_vADDR; + volatile void *new_pADDR, *new_vADDR; + + // TODO: cow + (void) cow; + + // dont reallocate kernel memeory!! + if ((volatile char *) old_pADDR <= kernel_end) + return old_pADDR; + + new_pADDR = alloc_phys_page(); + if (new_pADDR == NULL) + return NULL; + + old_vADDR = PAGE_MAPC(old_pADDR); + new_vADDR = PAGE_MAP(new_pADDR); + memcpyv(new_vADDR, old_vADDR, PAGE_SIZE); + return new_pADDR; +} + +volatile struct pt *pt_clone(volatile const struct pt *old_pPT, + bool cow) +{ + volatile const struct pt *old_vPT; + volatile struct pt *new_pPT, *new_vPT; + + new_pPT = alloc_phys_page(); + if (new_pPT == NULL) + return NULL; + + old_vPT = PT_MAPC(old_pPT); + new_vPT = PT_MAP(new_pPT); + memsetv(new_vPT, 0, PAGE_SIZE); + + new_vPT->count_high = old_vPT->count_high; + new_vPT->count_low = old_vPT->count_low; + + for (size_t i = 0; i < 512; i++) { + volatile const struct pte *old_vPTE; + volatile struct pte *new_vPTE; + volatile void *old_pADDR, *new_pADDR; + + old_vPTE = &old_vPT->entries[i]; + new_vPTE = &new_vPT->entries[i]; + + new_vPTE->execute_disable = old_vPTE->execute_disable; + new_vPTE->flags = old_vPTE->flags; + if (!(old_vPTE->flags & F_PRESENT)) + continue; + + new_vPTE->execute_disable = old_vPTE->execute_disable; + new_vPTE->flags = old_vPTE->flags; + + old_pADDR = + (volatile void *)((uintptr_t)old_vPTE->address + << 12); + new_pADDR = page_clone(old_pADDR, cow); + if (new_pADDR == NULL) + goto fail; + + new_vPTE->address = (uint64_t)new_pADDR >> 12; + } + + return new_pPT; + +fail: + pt_free(new_pPT, true); + return NULL; +} + +volatile struct pd *pd_clone(volatile const struct pd *old_pPD, + bool cow) +{ + volatile const struct pd *old_vPD; + volatile struct pd *new_pPD, *new_vPD; + + new_pPD = alloc_phys_page(); + if (new_pPD == NULL) + return NULL; + + old_vPD = PD_MAPC(old_pPD); + new_vPD = PD_MAP(new_pPD); + memsetv(new_vPD, 0, PAGE_SIZE); + + new_vPD->count = old_vPD->count; + + for (size_t i = 0; i < 512; i++) { + volatile const struct pde *old_vPDE; + volatile struct pde *new_vPDE; + volatile const struct pt *old_pPT; + volatile struct pt *new_pPT; + + old_vPDE = &old_vPD->entries[i]; + new_vPDE = &new_vPD->entries[i]; + + new_vPDE->execute_disable = old_vPDE->execute_disable; + new_vPDE->flags = old_vPDE->flags; + if (!(old_vPDE->flags & F_PRESENT)) + continue; + + old_pPT = + (volatile const struct pt *)((uintptr_t)old_vPDE->address + << 12); + new_pPT = pt_clone(old_pPT, cow); + if (new_pPT == NULL) + goto fail; + + new_vPDE->address = (uint64_t)new_pPT >> 12; + } + + return new_pPD; + +fail: + pd_free(new_pPD, true); + return NULL; +} + +volatile struct pdpt *pdpt_clone(volatile const struct pdpt *old_pPDPT, + bool cow) +{ + volatile const struct pdpt *old_vPDPT; + volatile struct pdpt *new_pPDPT, *new_vPDPT; + + new_pPDPT = alloc_phys_page(); + if (new_pPDPT == NULL) + return NULL; + + old_vPDPT = PDPT_MAPC(old_pPDPT); + new_vPDPT = PDPT_MAP(new_pPDPT); + memsetv(new_vPDPT, 0, PAGE_SIZE); + + new_vPDPT->count = old_vPDPT->count; + + for (size_t i = 0; i < 512; i++) { + volatile const struct pdpte *old_vPDPTE; + volatile struct pdpte *new_vPDPTE; + volatile const struct pd *old_pPD; + volatile struct pd *new_pPD; + + old_vPDPTE = &old_vPDPT->entries[i]; + new_vPDPTE = &new_vPDPT->entries[i]; + + new_vPDPTE->execute_disable = old_vPDPTE->execute_disable; + new_vPDPTE->flags = old_vPDPTE->flags; + if (!(old_vPDPTE->flags & F_PRESENT)) + continue; + + old_pPD = + (volatile const struct pd *)((uintptr_t)old_vPDPTE->address + << 12); + new_pPD = pd_clone(old_pPD, cow); + if (new_pPD == NULL) + goto fail; + + new_vPDPTE->address = (uint64_t)new_pPD >> 12; + } + + return new_pPDPT; + +fail: + pdpt_free(new_pPDPT, true); + return NULL; +} + +volatile struct pml4 *pml4_clone(volatile const struct pml4 *old_pPML4, + bool cow) +{ + volatile const struct pml4 *old_vPML4; + volatile struct pml4 *new_pPML4, *new_vPML4; + + new_pPML4 = pml4_alloc(); + if (new_pPML4 == NULL) + return NULL; + + old_vPML4 = PML4_MAPC(old_pPML4); + new_vPML4 = PML4_MAP(new_pPML4); + + new_vPML4->count = old_vPML4->count; + + for (size_t i = 0; i < 512; i++) { + volatile const struct pml4e *old_vPML4E; + volatile struct pml4e *new_vPML4E; + volatile const struct pdpt *old_pPDPT; + volatile struct pdpt *new_pPDPT; + + old_vPML4E = &old_vPML4->entries[i]; + new_vPML4E = &new_vPML4->entries[i]; + + new_vPML4E->execute_disable = old_vPML4E->execute_disable; + new_vPML4E->flags = old_vPML4E->flags; + if (!(old_vPML4E->flags & F_PRESENT)) + continue; + + old_pPDPT = + (volatile const struct pdpt *)((uintptr_t)old_vPML4E->address + << 12); + new_pPDPT = pdpt_clone(old_pPDPT, cow); + if (new_pPDPT == NULL) + goto fail; + + new_vPML4E->address = (uint64_t)new_pPDPT >> 12; + } + + return new_pPML4; + +fail: + pml4_free(new_pPML4, true); + return NULL; +} + /* page specific */ // locate a pte for a vitural address @@ -554,7 +740,7 @@ static volatile struct pte *page_locate(volatile struct pml4 *pPML4, return NULL; offset = ((uint64_t)vADDR >> 12) & 0x1ff; - vPT = pt_map(pPT); + vPT = PT_MAP(pPT); vPTE = &vPT->entries[offset]; if (vPTE->flags & F_PRESENT) @@ -587,7 +773,7 @@ static volatile struct pte *page_alloc(volatile struct pml4 *pPML4, void *vADDR, return NULL; offset = ((uint64_t)vADDR >> 12) & 0x1ff; - vPT = pt_map(pPT); + vPT = PT_MAP(pPT); vPTE = &vPT->entries[offset]; memsetv(vPTE, 0, sizeof(struct pte)); @@ -707,10 +893,7 @@ volatile void *pgdir_alloc(void) volatile void *pgdir_clone(volatile const void *old_pgdir, bool cow) { - // TODO: - (void)old_pgdir; - (void)cow; - return NULL; + return pml4_clone((volatile const struct pml4 *)old_pgdir, cow); } void pgdir_free(volatile void *addr) diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index f47f875..8971bcf 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -182,11 +182,11 @@ static bool segment_invalid(const struct memory_segment *segment) return true; if (segment->type != SEG_TYPE_FREE) return true; - if (segment->addr < (uintptr_t) kernel_start) + if (segment->addr < (uintptr_t)kernel_start) return true; if (segment->addr + segment->len < memory_start) return true; - if (segment->addr + segment->len < (uintptr_t) kernel_start) + if (segment->addr + segment->len < (uintptr_t)kernel_start) return true; return false; } @@ -200,7 +200,7 @@ static struct memory_segment clamp_segment(const struct memory_segment *segment) if (memory_start) start = memory_start; else - start = (uintptr_t) kernel_end; + start = (uintptr_t)kernel_end; if (segment->addr < start) { addr = start; diff --git a/kernel/procs.c b/kernel/procs.c index f3d855c..e2455ea 100644 --- a/kernel/procs.c +++ b/kernel/procs.c @@ -474,6 +474,7 @@ __attribute__((noreturn)) void dispatch(void) panic("dispatch queue remove failed, code %d", status); // set the process up for success + current_pcb->regs.cr3 = (uint64_t) mem_ctx_pgdir(current_pcb->memctx); current_pcb->state = PROC_STATE_RUNNING; current_pcb->ticks = 3; // ticks per process -- cgit v1.2.3-freya From c0a391cb11fe1b14f6622bad5697a72de1781eb2 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Mon, 28 Apr 2025 21:55:40 -0400 Subject: fmt --- kernel/memory/paging.c | 20 +++++++------------- kernel/procs.c | 2 +- kernel/syscall.c | 2 +- 3 files changed, 9 insertions(+), 15 deletions(-) (limited to 'kernel/memory/paging.c') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index b089895..763bdce 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -508,10 +508,10 @@ volatile void *page_clone(volatile void *old_pADDR, bool cow) volatile void *new_pADDR, *new_vADDR; // TODO: cow - (void) cow; + (void)cow; // dont reallocate kernel memeory!! - if ((volatile char *) old_pADDR <= kernel_end) + if ((volatile char *)old_pADDR <= kernel_end) return old_pADDR; new_pADDR = alloc_phys_page(); @@ -524,8 +524,7 @@ volatile void *page_clone(volatile void *old_pADDR, bool cow) return new_pADDR; } -volatile struct pt *pt_clone(volatile const struct pt *old_pPT, - bool cow) +volatile struct pt *pt_clone(volatile const struct pt *old_pPT, bool cow) { volatile const struct pt *old_vPT; volatile struct pt *new_pPT, *new_vPT; @@ -557,9 +556,7 @@ volatile struct pt *pt_clone(volatile const struct pt *old_pPT, new_vPTE->execute_disable = old_vPTE->execute_disable; new_vPTE->flags = old_vPTE->flags; - old_pADDR = - (volatile void *)((uintptr_t)old_vPTE->address - << 12); + old_pADDR = (volatile void *)((uintptr_t)old_vPTE->address << 12); new_pADDR = page_clone(old_pADDR, cow); if (new_pADDR == NULL) goto fail; @@ -574,8 +571,7 @@ fail: return NULL; } -volatile struct pd *pd_clone(volatile const struct pd *old_pPD, - bool cow) +volatile struct pd *pd_clone(volatile const struct pd *old_pPD, bool cow) { volatile const struct pd *old_vPD; volatile struct pd *new_pPD, *new_vPD; @@ -605,8 +601,7 @@ volatile struct pd *pd_clone(volatile const struct pd *old_pPD, continue; old_pPT = - (volatile const struct pt *)((uintptr_t)old_vPDE->address - << 12); + (volatile const struct pt *)((uintptr_t)old_vPDE->address << 12); new_pPT = pt_clone(old_pPT, cow); if (new_pPT == NULL) goto fail; @@ -652,8 +647,7 @@ volatile struct pdpt *pdpt_clone(volatile const struct pdpt *old_pPDPT, continue; old_pPD = - (volatile const struct pd *)((uintptr_t)old_vPDPTE->address - << 12); + (volatile const struct pd *)((uintptr_t)old_vPDPTE->address << 12); new_pPD = pd_clone(old_pPD, cow); if (new_pPD == NULL) goto fail; diff --git a/kernel/procs.c b/kernel/procs.c index e2455ea..5b03e73 100644 --- a/kernel/procs.c +++ b/kernel/procs.c @@ -474,7 +474,7 @@ __attribute__((noreturn)) void dispatch(void) panic("dispatch queue remove failed, code %d", status); // set the process up for success - current_pcb->regs.cr3 = (uint64_t) mem_ctx_pgdir(current_pcb->memctx); + current_pcb->regs.cr3 = (uint64_t)mem_ctx_pgdir(current_pcb->memctx); current_pcb->state = PROC_STATE_RUNNING; current_pcb->ticks = 3; // ticks per process diff --git a/kernel/syscall.c b/kernel/syscall.c index 2dd6460..403b3bd 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -327,7 +327,7 @@ static int sys_ticks(void) static int (*syscall_tbl[N_SYSCALLS])(void) = { [SYS_exit] = sys_exit, [SYS_waitpid] = sys_waitpid, - [SYS_fork] = sys_fork, [SYS_exec] = NULL, + [SYS_fork] = sys_fork, [SYS_exec] = NULL, [SYS_open] = NULL, [SYS_close] = NULL, [SYS_read] = NULL, [SYS_write] = sys_write, [SYS_getpid] = sys_getpid, [SYS_getppid] = sys_getppid, -- cgit v1.2.3-freya