diff --git a/src/arch/x86_64/include/arch/regs.h b/src/arch/x86_64/include/arch/regs.h index cf7ddd72..beca98b3 100644 --- a/src/arch/x86_64/include/arch/regs.h +++ b/src/arch/x86_64/include/arch/regs.h @@ -9,6 +9,7 @@ typedef uint64_t arch_reg; typedef struct{ uint64_t gsbase, fsbase; uint8_t fx[512]; + uint32_t mxcsr; } arch_extraregs; typedef struct{ @@ -16,6 +17,9 @@ typedef struct{ } arch_regs; void arch_regs_saveextra(arch_extraregs* regs); void arch_regs_setupextra(arch_extraregs* regs); + +void arch_regs_firsttimesetup(arch_regs* regs, arch_extraregs* xregs); + void arch_regs_setupkernel(arch_regs* regs, void* ip, void* stack, bool interrupts); void arch_regs_setupuser(arch_regs* regs, void* ip, void* stack, bool interrupts); diff --git a/src/arch/x86_64/regs.c b/src/arch/x86_64/regs.c index 2808c0d3..145bb8fc 100644 --- a/src/arch/x86_64/regs.c +++ b/src/arch/x86_64/regs.c @@ -1,12 +1,16 @@ #include #include +void arch_regs_firsttimesetup(arch_regs* regs, arch_extraregs* xregs){ + xregs->mxcsr = 0x1F80; // all exceptions masked +} + void arch_regs_saveextra(arch_extraregs* regs){ // user gs was swapped regs->gsbase = rdmsr(MSR_KERNELGSBASE); regs->fsbase = rdmsr(MSR_FSBASE); asm("fxsave (%%rax)" : : "a"(®s->fx[0])); - + asm("stmxcsr (%%rax)" : : "a"(®s->mxcsr)); } void arch_regs_setupextra(arch_extraregs* regs){ @@ -14,6 +18,7 @@ void arch_regs_setupextra(arch_extraregs* regs){ wrmsr(MSR_KERNELGSBASE, regs->gsbase); wrmsr(MSR_FSBASE, regs->fsbase); asm("fxrstor (%%rax)" : : "a"(®s->fx[0])); + asm("ldmxcsr (%%rax)" : : "a"(®s->mxcsr)); } void arch_regs_setupkernel(arch_regs* regs, void* ip, void* stack, bool interrupts){ diff --git a/src/sys/sched/scheduler.c b/src/sys/sched/scheduler.c index f3ac73b3..3b6b84b3 100644 --- a/src/sys/sched/scheduler.c +++ b/src/sys/sched/scheduler.c @@ -98,6 +98,8 @@ static thread_t* allocthread(proc_t* proc, state_t state, pid_t tid, size_t ksta thread->kernelstack = thread->kernelstackbase + kstacksize; thread->stacksize = kstacksize; + arch_regs_firsttimesetup(thread->regs, &thread->extraregs); + return thread; }