Kernel: store/load sse/mmx/fpu state on isr/irq/syscall

I haven't tested this yet but should be fine. This will be optimized
to only save state from threads that are using it
This commit is contained in:
Bananymous 2023-07-31 22:28:57 +03:00
parent e86e755c51
commit 8b1bccb79b
3 changed files with 17 additions and 0 deletions

View File

@ -138,6 +138,8 @@ namespace IDT
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, Kernel::InterruptStack& interrupt_stack, const Registers* regs) extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, Kernel::InterruptStack& interrupt_stack, const Registers* regs)
{ {
Kernel::Thread::current().save_sse();
pid_t tid = Kernel::Scheduler::current_tid(); pid_t tid = Kernel::Scheduler::current_tid();
pid_t pid = tid ? Kernel::Process::current().pid() : 0; pid_t pid = tid ? Kernel::Process::current().pid() : 0;
@ -205,10 +207,14 @@ namespace IDT
default: default:
break; break;
} }
Kernel::Thread::current().load_sse();
} }
extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack) extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack)
{ {
Kernel::Thread::current().save_sse();
if (Kernel::Scheduler::current_tid()) if (Kernel::Scheduler::current_tid())
{ {
Kernel::Thread::current().set_return_rsp(interrupt_stack.rsp); Kernel::Thread::current().set_return_rsp(interrupt_stack.rsp);
@ -242,6 +248,8 @@ namespace IDT
default: default:
break; break;
} }
Kernel::Thread::current().load_sse();
} }
static void flush_idt() static void flush_idt()

View File

@ -82,6 +82,9 @@ namespace Kernel
bool is_userspace() const { return m_is_userspace; } bool is_userspace() const { return m_is_userspace; }
void save_sse() { asm volatile("fxsave %0" :: "m"(m_sse_storage)); }
void load_sse() { asm volatile("fxrstor %0" :: "m"(m_sse_storage)); }
private: private:
Thread(pid_t tid, Process*); Thread(pid_t tid, Process*);
void on_exit(); void on_exit();
@ -111,6 +114,8 @@ namespace Kernel
uint64_t m_terminate_blockers { 0 }; uint64_t m_terminate_blockers { 0 };
alignas(16) uint8_t m_sse_storage[512];
friend class TerminateBlocker; friend class TerminateBlocker;
friend class Scheduler; friend class Scheduler;
}; };

View File

@ -30,6 +30,8 @@ namespace Kernel
return 0; return 0;
} }
Thread::current().save_sse();
asm volatile("sti"); asm volatile("sti");
(void)arg1; (void)arg1;
@ -183,6 +185,8 @@ namespace Kernel
break; break;
} }
Thread::current().load_sse();
if (ret.is_error()) if (ret.is_error())
return -ret.error().get_error_code(); return -ret.error().get_error_code();
return ret.value(); return ret.value();