Module: xenomai-forge Branch: master Commit: ee00dca4d6f8cd7b9fcf9506e3be0f4af950f232 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=ee00dca4d6f8cd7b9fcf9506e3be0f4af950f232
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Fri Feb 8 17:23:31 2013 +0100 cobalt/x86: fix FPU handling --- include/asm-x86/thread.h | 2 - kernel/cobalt/arch/x86/thread.c | 96 ++++----------------------------------- 2 files changed, 10 insertions(+), 88 deletions(-) diff --git a/include/asm-x86/thread.h b/include/asm-x86/thread.h index 7ca11cf..af1ff2a 100644 --- a/include/asm-x86/thread.h +++ b/include/asm-x86/thread.h @@ -34,8 +34,6 @@ struct xnarchtcb { unsigned long *ipp; x86_fpustate *fpup; unsigned int is_root: 1; - unsigned int ts_usedfpu: 1; - unsigned int cr0_ts: 1; struct { unsigned long ip; unsigned long ax; diff --git a/kernel/cobalt/arch/x86/thread.c b/kernel/cobalt/arch/x86/thread.c index 7631507..61cb365 100644 --- a/kernel/cobalt/arch/x86/thread.c +++ b/kernel/cobalt/arch/x86/thread.c @@ -88,21 +88,11 @@ void xnarch_leave_root(struct xnarchtcb *rootcb) { struct task_struct *p = current; - rootcb->ts_usedfpu = wrap_test_fpu_used(p) != 0; - rootcb->cr0_ts = (read_cr0() & 8) != 0; #ifdef CONFIG_X86_64 rootcb->spp = &p->thread.sp; rootcb->ipp = &p->thread.rip; #endif - /* So that xnarch_save_fpu() will operate on the right FPU area. */ - if (rootcb->cr0_ts || rootcb->ts_usedfpu) - rootcb->fpup = x86_fpustate_ptr(&p->thread); - else - /* - * The kernel is currently using fpu in kernel-space, - * do not clobber the user-space fpu backup area. - */ - rootcb->fpup = &rootcb->i387; + rootcb->fpup = x86_fpustate_ptr(&p->thread); } void xnarch_switch_to(struct xnarchtcb *out_tcb, struct xnarchtcb *in_tcb) @@ -253,98 +243,32 @@ int xnarch_handle_fpu_fault(struct xnarchtcb *tcb) void xnarch_save_fpu(struct xnarchtcb *tcb) { - struct task_struct *p = tcb->core.host_task; - - if (tcb->is_root == 0) { - /* fpu not used or already saved by __switch_to. */ - if (wrap_test_fpu_used(p) == 0) - return; - - /* - * Tell Linux that we already saved the state of the - * FPU hardware of this task. - */ - wrap_clear_fpu_used(p); - } else { - if (tcb->cr0_ts || - (tcb->ts_usedfpu && wrap_test_fpu_used(p) == 0)) - return; - - wrap_clear_fpu_used(p); - } - - clts(); - - __do_save_i387(tcb->fpup); + /* Already saved by __switch_to */ } void xnarch_restore_fpu(struct xnarchtcb *tcb) { struct task_struct *p = tcb->core.host_task; - if (tcb->is_root == 0) { - if (tsk_used_math(p) == 0) { - stts(); - return; /* Uninit fpu area -- do not restore. */ - } - - /* - * Tell Linux that this task has altered the state of - * the FPU hardware. - */ - wrap_set_fpu_used(p); - } else { - /* - * Restore state of FPU only if TS bit in cr0 was - * clear. - */ - if (tcb->cr0_ts) { - wrap_clear_fpu_used(p); - stts(); - return; - } - - if (tcb->ts_usedfpu && !wrap_test_fpu_used(p)) { - /* - * __switch_to saved the fpu context, no need - * to restore it since we are switching to - * root, where fpu can be in lazy state. - */ - stts(); - return; - } + if (tcb->is_root || tsk_used_math(p) == 0) { + /* Restore lazy mode */ + return; } + /* * Restore the FPU hardware with valid fp registers from a - * user-space or kernel thread. + * RT user-space or kernel thread. */ clts(); __do_restore_i387(tcb->fpup); + wrap_set_fpu_used(p); } void xnarch_enable_fpu(struct xnarchtcb *tcb) { - struct task_struct *p = tcb->core.host_task; - - if (tcb->is_root == 0) { - if (tsk_used_math(p) == 0) - return; - /* - * We used to test here if __switch_to had not saved - * current fpu state, but this can not happen, since - * xnarch_enable_fpu may only be called when switching - * back to a user-space task after one or several - * switches to non-fpu kernel-space real-time tasks, - * so xnarch_switch_to never uses __switch_to. - */ - } else if (tcb->cr0_ts) - return; - - /* The comment in the non-root case applies here too. */ - - clts(); + xnarch_restore_fpu(tcb); } #endif /* CONFIG_XENO_HW_FPU */ @@ -354,8 +278,8 @@ void xnarch_init_root_tcb(struct xnarchtcb *tcb) tcb->sp = 0; tcb->spp = &tcb->sp; tcb->ipp = &tcb->ip; - tcb->fpup = NULL; tcb->is_root = 1; + tcb->fpup = NULL; } void xnarch_init_shadow_tcb(struct xnarchtcb *tcb) _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git