From 1b8d431a65728589b2300964f7dfe4ce72d0ac96 Mon Sep 17 00:00:00 2001 From: Pawel Wieczorkiewicz Date: Sun, 27 Aug 2023 17:12:19 +0200 Subject: [PATCH] arch,entry,usermode: fix user pagetable mappings alignment The exception handlers as well as interrupt handlers need to be properly mapped into user pagetables. Add global symbols to find their addresses and align the beginning on a page boundary. Similar entry_usermode() and syscall_handler_entry() need to be aligned and ideally share the same page. The syscall_exit() and similar routines do not need user pagetable mappings. Add also an explicit mapping for user_cr3 variable. Signed-off-by: Pawel Wieczorkiewicz --- arch/x86/entry.S | 6 +++++- common/usermode.c | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/x86/entry.S b/arch/x86/entry.S index 16abb335..e1c46c5c 100644 --- a/arch/x86/entry.S +++ b/arch/x86/entry.S @@ -107,6 +107,8 @@ ENTRY(handle_exception) IRET END_FUNC(handle_exception) +.align PAGE_SIZE +GLOBAL(exception_handlers) exception_handler DE X86_EX_DE 0 exception_handler DB X86_EX_DB 0 exception_handler NMI X86_EX_NMI 0 @@ -130,6 +132,7 @@ exception_handler XM X86_EX_XM 0 exception_handler VE X86_EX_VE 0 exception_handler SE X86_EX_SE 1 +GLOBAL(interrupt_handlers) interrupt_handler timer timer_interrupt_handler interrupt_handler uart uart_interrupt_handler interrupt_handler keyboard keyboard_interrupt_handler @@ -137,6 +140,7 @@ interrupt_handler keyboard keyboard_interrupt_handler interrupt_handler acpi acpi_interrupt_handler #endif +.align PAGE_SIZE ENTRY(syscall_exit) POPF @@ -157,6 +161,7 @@ ENTRY(terminate_user_task) ret END_FUNC(terminate_user_task) +.align PAGE_SIZE ENTRY(enter_usermode) /* FIXME: Add 32-bit support */ @@ -184,7 +189,6 @@ ENTRY(enter_usermode) IRET END_FUNC(enter_usermode) -.align PAGE_SIZE ENTRY(syscall_handler_entry) SAVE_CALLEE_SAVED_REGS syscall_from_usermode diff --git a/common/usermode.c b/common/usermode.c index a214d64a..e520a9c8 100644 --- a/common/usermode.c +++ b/common/usermode.c @@ -28,6 +28,9 @@ #include #include +extern void *exception_handlers; +extern void *interrupt_handlers; + long syscall_handler(long syscall_nr, long arg1, long arg2, long arg3, long arg4, long arg5) { switch (syscall_nr) { @@ -89,6 +92,9 @@ static void init_syscall(void) { void init_usermode(percpu_t *percpu) { vmap_user_4k(&cr3, virt_to_mfn(&cr3), L1_PROT); + vmap_user_4k(&user_cr3, virt_to_mfn(&user_cr3), L1_PROT); + vmap_user_4k(&exception_handlers, virt_to_mfn(&exception_handlers), L1_PROT); + vmap_user_4k(&interrupt_handlers, virt_to_mfn(&interrupt_handlers), L1_PROT); vmap_user_4k(&enter_usermode, virt_to_mfn(&enter_usermode), L1_PROT); vmap_user_4k(&syscall_handler_entry, virt_to_mfn(&syscall_handler_entry), L1_PROT); init_syscall();