diff --git a/src/arch/x86/cpu.h b/src/arch/x86/cpu.h index dc77f68..bfbbb87 100644 --- a/src/arch/x86/cpu.h +++ b/src/arch/x86/cpu.h @@ -35,6 +35,9 @@ typedef struct { bool xsave; bool avx; bool avx512; + bool umip; + bool smep; + bool smap; } CpuFeatures; extern CpuFeatures CPU_FEATURES; diff --git a/src/arch/x86/mem/misc.S b/src/arch/x86/mem/misc.S index b2ff7ff..e4ca28c 100644 --- a/src/arch/x86/mem/misc.S +++ b/src/arch/x86/mem/misc.S @@ -18,7 +18,9 @@ arch_mem_copy_to_user: mov %rax, %gs:X86TASK_HANDLER_IP_OFF mov %rsp, %gs:X86TASK_HANDLER_SP_OFF + stac call memcpy + clac xor %edi, %edi mov %rdi, %gs:X86TASK_HANDLER_IP_OFF @@ -44,7 +46,9 @@ arch_mem_copy_to_kernel: mov %rax, %gs:X86TASK_HANDLER_IP_OFF mov %rsp, %gs:X86TASK_HANDLER_SP_OFF + stac call memcpy + clac xor %edi, %edi mov %rdi, %gs:X86TASK_HANDLER_IP_OFF diff --git a/src/arch/x86/sched/usermode.S b/src/arch/x86/sched/usermode.S index 583c2cc..153b2f9 100644 --- a/src/arch/x86/sched/usermode.S +++ b/src/arch/x86/sched/usermode.S @@ -14,8 +14,12 @@ x86_usermode_ret: swapgs + // rip pop %rcx + // arg pop %rdi + // rsp + pop %rsp xor %eax, %eax xor %edx, %edx diff --git a/src/arch/x86/sched/x86_task.c b/src/arch/x86/sched/x86_task.c index 33d5130..e6dad1e 100644 --- a/src/arch/x86/sched/x86_task.c +++ b/src/arch/x86/sched/x86_task.c @@ -30,6 +30,7 @@ typedef struct { void (*usermode_ret)(); void (*fn)(void*); void* arg; + void* rsp; u64 null_rbp; u64 null_rip; } UserInitStackFrame; @@ -81,14 +82,15 @@ Task* arch_create_user_task(Process* process, const char* name, void (*fn)(void* u8* stack_base = stack; memset(stack, 0, USER_STACK_SIZE); task->stack_base = (usize) user_stack; - stack += USER_STACK_SIZE - sizeof(UserInitStackFrame); - user_stack += USER_STACK_SIZE - sizeof(UserInitStackFrame); + stack += USER_STACK_SIZE; + user_stack += USER_STACK_SIZE; - UserInitStackFrame* frame = (UserInitStackFrame*) stack; + UserInitStackFrame* frame = (UserInitStackFrame*) (task->kernel_rsp - sizeof(UserInitStackFrame)); frame->after_switch = x86_switch_from_init; frame->usermode_ret = x86_usermode_ret; frame->fn = fn; frame->arg = arg; + frame->rsp = user_stack; frame->null_rbp = 0; frame->null_rip = 0; @@ -97,7 +99,7 @@ Task* arch_create_user_task(Process* process, const char* name, void (*fn)(void* strncpy(task->common.name, name, sizeof(task->common.name)); task->common.status = TASK_STATUS_READY; - task->rsp = (usize) user_stack; + task->rsp = (usize) frame; task->common.level = SCHED_MAX_LEVEL - 1; task->user = true; task->common.priority = 0; diff --git a/src/arch/x86/smp.c b/src/arch/x86/smp.c index 5e2507b..1248db8 100644 --- a/src/arch/x86/smp.c +++ b/src/arch/x86/smp.c @@ -109,6 +109,19 @@ static void init_simd() { init_simd(); + u64 cr4; + __asm__ volatile("mov %%cr4, %0" : "=r"(cr4)); + if (CPU_FEATURES.umip) { + cr4 |= 1 << 11; + } + if (CPU_FEATURES.smep) { + cr4 |= 1 << 20; + } + if (CPU_FEATURES.smap) { + cr4 |= 1 << 21; + } + __asm__ volatile("mov %0, %%cr4" : : "r"(cr4)); + lapic_init(); lapic_timer_init(); @@ -145,6 +158,16 @@ static void detect_cpu_features() { CPU_FEATURES.xsave_area_size = cpuid(0xD, 0).ecx; } + info = cpuid(7, 0); + if (info.ecx & 1 << 2) { + CPU_FEATURES.umip = true; + } + if (info.ebx & 1 << 7) { + CPU_FEATURES.smep = true; + } + if (info.ebx & 1 << 20) { + CPU_FEATURES.smap = true; + } } void arch_init_smp() { @@ -180,6 +203,21 @@ void arch_init_smp() { kprintf("[kernel][timer]: apic frequency %uhz\n", CPUS[0].lapic_timer.freq); init_simd(); + u64 cr4; + __asm__ volatile("mov %%cr4, %0" : "=r"(cr4)); + if (CPU_FEATURES.umip) { + kprintf("[kernel][x86]: enabling UMIP\n"); + cr4 |= 1 << 11; + } + if (CPU_FEATURES.smep) { + kprintf("[kernel][x86]: enabling SMEP\n"); + cr4 |= 1 << 20; + } + if (CPU_FEATURES.smap) { + kprintf("[kernel][x86]: enabling SMAP\n"); + cr4 |= 1 << 21; + } + __asm__ volatile("mov %0, %%cr4" : : "r"(cr4)); x86_init_usermode(); sched_init(true);