Skip to content

Commit

Permalink
arch,entry,usermode: fix user pagetable mappings alignment
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
wipawel committed Aug 28, 2023
1 parent 9cff8c9 commit f597ad1
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
10 changes: 9 additions & 1 deletion arch/x86/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -129,14 +131,18 @@ exception_handler MC X86_EX_MC 0
exception_handler XM X86_EX_XM 0
exception_handler VE X86_EX_VE 0
exception_handler SE X86_EX_SE 1
GLOBAL(end_exception_handlers)

GLOBAL(interrupt_handlers)
interrupt_handler timer timer_interrupt_handler
interrupt_handler uart uart_interrupt_handler
interrupt_handler keyboard keyboard_interrupt_handler
#ifdef KTF_ACPICA
interrupt_handler acpi acpi_interrupt_handler
#endif
GLOBAL(end_interrupt_handlers)

.align PAGE_SIZE
ENTRY(syscall_exit)
POPF

Expand All @@ -157,6 +163,8 @@ ENTRY(terminate_user_task)
ret
END_FUNC(terminate_user_task)

.align PAGE_SIZE
GLOBAL(usermode_helpers)
ENTRY(enter_usermode)
/* FIXME: Add 32-bit support */

Expand Down Expand Up @@ -184,7 +192,6 @@ ENTRY(enter_usermode)
IRET
END_FUNC(enter_usermode)

.align PAGE_SIZE
ENTRY(syscall_handler_entry)
SAVE_CALLEE_SAVED_REGS
syscall_from_usermode
Expand All @@ -206,6 +213,7 @@ ENTRY(syscall_handler_entry)
RESTORE_CALLEE_SAVED_REGS
SYSRET
END_FUNC(syscall_handler_entry)
GLOBAL(end_usermode_helpers)

SECTION(.text.user, "ax", 16)
ENTRY(usermode_stub)
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/pagetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include <spinlock.h>
#include <string.h>

cr3_t cr3;
cr3_t __aligned(PAGE_SIZE) cr3;
cr3_t user_cr3;

static inline const char *dump_pte_flags(char *buf, size_t size, pte_t pte) {
Expand Down
17 changes: 15 additions & 2 deletions common/usermode.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
#include <processor.h>
#include <usermode.h>

extern char exception_handlers[], end_exception_handlers[];
extern char interrupt_handlers[], end_interrupt_handlers[];
extern char usermode_helpers[], end_usermode_helpers[];

long syscall_handler(long syscall_nr, long arg1, long arg2, long arg3, long arg4,
long arg5) {
switch (syscall_nr) {
Expand Down Expand Up @@ -89,8 +93,17 @@ static void init_syscall(void) {

void init_usermode(percpu_t *percpu) {
vmap_user_4k(&cr3, virt_to_mfn(&cr3), 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);
vmap_user_4k(&user_cr3, virt_to_mfn(&user_cr3), L1_PROT);

BUG_ON(end_exception_handlers - exception_handlers > (long) PAGE_SIZE);
vmap_user_4k(exception_handlers, virt_to_mfn(exception_handlers), L1_PROT);

BUG_ON(end_interrupt_handlers - interrupt_handlers > (long) PAGE_SIZE);
vmap_user_4k(interrupt_handlers, virt_to_mfn(interrupt_handlers), L1_PROT);

BUG_ON(end_usermode_helpers - usermode_helpers > (long) PAGE_SIZE);
vmap_user_4k(usermode_helpers, virt_to_mfn(usermode_helpers), L1_PROT);

init_syscall();
}

Expand Down

0 comments on commit f597ad1

Please sign in to comment.