Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Further fixes for usermode handling #289

Merged
merged 3 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 46 additions & 41 deletions arch/x86/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,23 @@ ENTRY(asm_interrupt_handler_\sym)
END_FUNC(asm_interrupt_handler_\sym)
.endm

ENTRY(handle_exception)
cld
SAVE_ALL_REGS

mov %_ASM_SP, %_ASM_DI
call do_exception

RESTORE_ALL_REGS

add $8, %_ASM_SP

enter_to_usermode
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 @@ -114,29 +131,40 @@ 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)

ENTRY(handle_exception)
cld
SAVE_ALL_REGS

mov %_ASM_SP, %_ASM_DI
call do_exception

RESTORE_ALL_REGS

add $8, %_ASM_SP

enter_to_usermode
IRET
END_FUNC(handle_exception)

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

/* Save exit code to return value register (AX) */
mov %_ASM_SI, cpu_regs_ax(%_ASM_SP)
RESTORE_ALL_REGS

ret
END_FUNC(syscall_exit)

ENTRY(terminate_user_task)
SWITCH_STACK
POPF

movl $-EFAULT, cpu_regs_ax(%_ASM_SP)
RESTORE_ALL_REGS

ret
END_FUNC(terminate_user_task)

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

Expand All @@ -145,10 +173,9 @@ ENTRY(enter_usermode)
PUSHF

/* Save stack pointer onto per-cpu */
mov %_ASM_SP, %gs:usermode_private
mov %_ASM_DX, %gs:(usermode_private)

/* Move to user stack */
mov %_ASM_DX, %_ASM_SP
syscall_to_usermode
minipli-oss marked this conversation as resolved.
Show resolved Hide resolved

/* SS + SP */
push $__USER_DS
wipawel marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -162,32 +189,9 @@ ENTRY(enter_usermode)
/* CS + IP */
push $__USER_CS
push $usermode_stub

enter_to_usermode
IRET
END_FUNC(enter_usermode)

ENTRY(syscall_exit)
POPF

/* Save exit code to return value register (AX) */
mov %_ASM_SI, cpu_regs_ax(%_ASM_SP)
RESTORE_ALL_REGS

ret
END_FUNC(syscall_exit)

ENTRY(terminate_user_task)
SWITCH_STACK
POPF

movl $-EFAULT, cpu_regs_ax(%_ASM_SP)
RESTORE_ALL_REGS

ret
END_FUNC(terminate_user_task)

.align PAGE_SIZE
ENTRY(syscall_handler_entry)
SAVE_CALLEE_SAVED_REGS
syscall_from_usermode
Expand All @@ -209,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