]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
fix: ring3 private address space + VTIME timer frequency regression
authorTulio A M Mendes <[email protected]>
Sat, 14 Feb 2026 20:14:44 +0000 (17:14 -0300)
committerTulio A M Mendes <[email protected]>
Sat, 14 Feb 2026 20:14:44 +0000 (17:14 -0300)
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

src/arch/x86/usermode.c
src/kernel/tty.c

index d5a10cf2c9d19da23fd1b60087bdbd43aa612fc8..8a4e4b64e2f6ce64aab6e2d22d465cdcfc08c4c3 100644 (file)
@@ -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);
 }
index 93308115c88e11ff5137ac3896f3b7fcd8628a76..e9e9fc63a93f0d354003a6bd901d509cd9b449c3 100644 (file)
@@ -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;
     }