From: Tulio A M Mendes Date: Sat, 14 Feb 2026 20:14:44 +0000 (-0300) Subject: fix: ring3 private address space + VTIME timer frequency regression X-Git-Url: https://projects.tadryanom.me/sitemap.xml?a=commitdiff_plain;h=d87cd6e77bff3837eb6f6afa9b2d6ec2e8a77ef4;p=AdrOS.git fix: ring3 private address space + VTIME timer frequency regression 1. **ring3 test: create private address space** - Previously, x86_usermode_test_start() mapped user pages at 0x00400000 and 0x00800000 directly into kernel_as (shared by all kernel threads). These pages were never cleaned up on exit. - Now creates a private AS via vmm_as_create_kernel_clone(), switches to it, then maps user pages there. On process exit, vmm_as_destroy() properly frees the pages. - Eliminates kernel_as contamination that could interfere with other processes (init.elf, /bin/sh). 2. **TTY VTIME: fix hardcoded 50Hz tick rate** - tty_read_kbuf() calculated non-canonical VTIME timeout as vtime*5 (hardcoded for 50Hz). At 100Hz this gave half the intended timeout, causing premature read returns. - Now uses vtime*(TIMER_HZ/10) which is correct at any tick rate. Tests: 20/20 smoke (8s), 16/16 battery, cppcheck clean --- diff --git a/src/arch/x86/usermode.c b/src/arch/x86/usermode.c index d5a10cf..8a4e4b6 100644 --- a/src/arch/x86/usermode.c +++ b/src/arch/x86/usermode.c @@ -4,8 +4,9 @@ #include "pmm.h" #include "vmm.h" #include "console.h" +#include "process.h" #include "utils.h" - #include "arch/x86/usermode.h" +#include "arch/x86/usermode.h" #include "arch/x86/idt.h" #if defined(__i386__) @@ -150,11 +151,6 @@ void x86_usermode_test_start(void) { return; } - vmm_map_page((uint64_t)(uintptr_t)code_phys, (uint64_t)user_code_vaddr, - VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER); - vmm_map_page((uint64_t)(uintptr_t)stack_phys, (uint64_t)user_stack_vaddr, - VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER); - const uintptr_t base = user_code_vaddr; const uint32_t addr_t1_ok = (uint32_t)(base + 0x200); const uint32_t addr_t1_fail = (uint32_t)(base + 0x210); @@ -260,6 +256,27 @@ void x86_usermode_test_start(void) { memcpy((void*)((uintptr_t)code_phys + 0x250), "T3 FAIL\n", t3_fail_len); memcpy((void*)((uintptr_t)code_phys + 0x300), "Hello from ring3!\n", msg_len); + /* Create a private address space so the ring3 user pages do NOT + * pollute kernel_as (which is shared by all kernel threads). + * Code/data was emitted above via the identity mapping still + * active in kernel_as; now we switch to the new AS and map the + * physical pages at their user virtual addresses. */ + uintptr_t ring3_as = vmm_as_create_kernel_clone(); + if (!ring3_as) { + kprintf("[USER] Failed to create ring3 address space.\n"); + pmm_free_page(code_phys); + pmm_free_page(stack_phys); + return; + } + + current_process->addr_space = ring3_as; + vmm_as_activate(ring3_as); + + vmm_map_page((uint64_t)(uintptr_t)code_phys, (uint64_t)user_code_vaddr, + VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER); + vmm_map_page((uint64_t)(uintptr_t)stack_phys, (uint64_t)user_stack_vaddr, + VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER); + uintptr_t user_esp = user_stack_vaddr + 4096; x86_enter_usermode(user_code_vaddr, user_esp); } diff --git a/src/kernel/tty.c b/src/kernel/tty.c index 9330811..e9e9fc6 100644 --- a/src/kernel/tty.c +++ b/src/kernel/tty.c @@ -11,6 +11,7 @@ #include "hal/cpu.h" #include "hal/uart.h" +#include "timer.h" #include "utils.h" #define TTY_LINE_MAX 256 @@ -163,10 +164,10 @@ int tty_read_kbuf(void* kbuf, uint32_t len) { if (target > len) target = len; if (target == 0) target = 1; - /* VTIME in tenths-of-second => ticks at 50 Hz */ + /* VTIME in tenths-of-second => ticks at TIMER_HZ */ uint32_t timeout_ticks = 0; if (vtime > 0) { - timeout_ticks = (vtime * 5U); + timeout_ticks = vtime * (TIMER_HZ / 10); if (timeout_ticks == 0) timeout_ticks = 1; }