1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 01:07:35 +00:00

Kernel: Save/restore the SSE context on context switch.

This commit is contained in:
Andreas Kling 2019-03-27 15:27:45 +01:00
parent 44e1e7423f
commit e9f2cc3595
4 changed files with 10 additions and 15 deletions

View file

@ -15,7 +15,7 @@ Thread::Thread(Process& process)
{ {
dbgprintf("Thread: New thread TID=%u in %s(%u)\n", m_tid, process.name().characters(), process.pid()); dbgprintf("Thread: New thread TID=%u in %s(%u)\n", m_tid, process.name().characters(), process.pid());
set_default_signal_dispositions(); set_default_signal_dispositions();
memset(&m_fpu_state, 0, sizeof(FPUState)); m_fpu_state = (FPUState*)kmalloc_aligned(sizeof(FPUState), 16);
memset(&m_tss, 0, sizeof(m_tss)); memset(&m_tss, 0, sizeof(m_tss));
// Only IF is set when a process boots. // Only IF is set when a process boots.
@ -68,6 +68,7 @@ Thread::Thread(Process& process)
Thread::~Thread() Thread::~Thread()
{ {
dbgprintf("~Thread{%p}\n", this); dbgprintf("~Thread{%p}\n", this);
kfree_aligned(m_fpu_state);
{ {
InterruptDisabler disabler; InterruptDisabler disabler;
g_threads->remove(this); g_threads->remove(this);
@ -493,7 +494,8 @@ Thread* Thread::clone(Process& process)
auto* clone = new Thread(process); auto* clone = new Thread(process);
memcpy(clone->m_signal_action_data, m_signal_action_data, sizeof(m_signal_action_data)); memcpy(clone->m_signal_action_data, m_signal_action_data, sizeof(m_signal_action_data));
clone->m_signal_mask = m_signal_mask; clone->m_signal_mask = m_signal_mask;
clone->m_fpu_state = m_fpu_state; clone->m_fpu_state = (FPUState*)kmalloc_aligned(sizeof(FPUState), 16);
memcpy(clone->m_fpu_state, m_fpu_state, sizeof(FPUState));
clone->m_has_used_fpu = m_has_used_fpu; clone->m_has_used_fpu = m_has_used_fpu;
return clone; return clone;
} }

View file

@ -111,7 +111,7 @@ public:
bool has_unmasked_pending_signals() const; bool has_unmasked_pending_signals() const;
void terminate_due_to_signal(byte signal); void terminate_due_to_signal(byte signal);
FPUState& fpu_state() { return m_fpu_state; } FPUState& fpu_state() { return *m_fpu_state; }
bool has_used_fpu() const { return m_has_used_fpu; } bool has_used_fpu() const { return m_has_used_fpu; }
void set_has_used_fpu(bool b) { m_has_used_fpu = b; } void set_has_used_fpu(bool b) { m_has_used_fpu = b; }
@ -159,7 +159,7 @@ private:
Vector<int> m_select_write_fds; Vector<int> m_select_write_fds;
Vector<int> m_select_exceptional_fds; Vector<int> m_select_exceptional_fds;
State m_state { Invalid }; State m_state { Invalid };
FPUState m_fpu_state; FPUState* m_fpu_state { nullptr };
bool m_select_has_timeout { false }; bool m_select_has_timeout { false };
bool m_has_used_fpu { false }; bool m_has_used_fpu { false };
bool m_was_interrupted_while_blocked { false }; bool m_was_interrupted_while_blocked { false };

View file

@ -190,14 +190,14 @@ void exception_7_handler(RegisterDump& regs)
if (g_last_fpu_thread == current) if (g_last_fpu_thread == current)
return; return;
if (g_last_fpu_thread) { if (g_last_fpu_thread) {
asm volatile("fnsave %0":"=m"(g_last_fpu_thread->fpu_state())); asm volatile("fxsave %0":"=m"(g_last_fpu_thread->fpu_state()));
} else { } else {
asm volatile("fnclex"); asm volatile("fnclex");
} }
g_last_fpu_thread = current; g_last_fpu_thread = current;
if (current->has_used_fpu()) { if (current->has_used_fpu()) {
asm volatile("frstor %0"::"m"(current->fpu_state())); asm volatile("fxrstor %0"::"m"(current->fpu_state()));
} else { } else {
asm volatile("fninit"); asm volatile("fninit");
current->set_has_used_fpu(true); current->set_has_used_fpu(true);

View file

@ -234,15 +234,8 @@ struct [[gnu::packed]] RegisterDumpWithExceptionCode {
word ss_if_crossRing; word ss_if_crossRing;
}; };
struct FPUState { struct [[gnu::aligned(16)]] FPUState {
dword cwd; byte buffer[512];
dword swd;
dword twd;
dword fip;
dword fcs;
dword foo;
dword fos;
dword st[20];
}; };
inline constexpr dword page_base_of(dword address) inline constexpr dword page_base_of(dword address)