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:
parent
44e1e7423f
commit
e9f2cc3595
4 changed files with 10 additions and 15 deletions
|
@ -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());
|
||||
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));
|
||||
|
||||
// Only IF is set when a process boots.
|
||||
|
@ -68,6 +68,7 @@ Thread::Thread(Process& process)
|
|||
Thread::~Thread()
|
||||
{
|
||||
dbgprintf("~Thread{%p}\n", this);
|
||||
kfree_aligned(m_fpu_state);
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
g_threads->remove(this);
|
||||
|
@ -493,7 +494,8 @@ Thread* Thread::clone(Process& process)
|
|||
auto* clone = new Thread(process);
|
||||
memcpy(clone->m_signal_action_data, m_signal_action_data, sizeof(m_signal_action_data));
|
||||
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;
|
||||
return clone;
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ public:
|
|||
bool has_unmasked_pending_signals() const;
|
||||
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; }
|
||||
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_exceptional_fds;
|
||||
State m_state { Invalid };
|
||||
FPUState m_fpu_state;
|
||||
FPUState* m_fpu_state { nullptr };
|
||||
bool m_select_has_timeout { false };
|
||||
bool m_has_used_fpu { false };
|
||||
bool m_was_interrupted_while_blocked { false };
|
||||
|
|
|
@ -190,14 +190,14 @@ void exception_7_handler(RegisterDump& regs)
|
|||
if (g_last_fpu_thread == current)
|
||||
return;
|
||||
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 {
|
||||
asm volatile("fnclex");
|
||||
}
|
||||
g_last_fpu_thread = current;
|
||||
|
||||
if (current->has_used_fpu()) {
|
||||
asm volatile("frstor %0"::"m"(current->fpu_state()));
|
||||
asm volatile("fxrstor %0"::"m"(current->fpu_state()));
|
||||
} else {
|
||||
asm volatile("fninit");
|
||||
current->set_has_used_fpu(true);
|
||||
|
|
|
@ -234,15 +234,8 @@ struct [[gnu::packed]] RegisterDumpWithExceptionCode {
|
|||
word ss_if_crossRing;
|
||||
};
|
||||
|
||||
struct FPUState {
|
||||
dword cwd;
|
||||
dword swd;
|
||||
dword twd;
|
||||
dword fip;
|
||||
dword fcs;
|
||||
dword foo;
|
||||
dword fos;
|
||||
dword st[20];
|
||||
struct [[gnu::aligned(16)]] FPUState {
|
||||
byte buffer[512];
|
||||
};
|
||||
|
||||
inline constexpr dword page_base_of(dword address)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue