Module: xenomai-gch
Branch: next
Commit: f3a384bd0e683ac28d49ef437f21f4ee75f8a60a
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=f3a384bd0e683ac28d49ef437f21f4ee75f8a60a

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sun Dec 20 20:56:18 2015 +0100

cobalt/x86: FPU fixes for Linux 4.1

---

 .../cobalt/arch/x86/include/asm/xenomai/wrappers.h  |   19 +++++++++++++++++++
 kernel/cobalt/arch/x86/thread.c                     |   13 ++++++++-----
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/wrappers.h 
b/kernel/cobalt/arch/x86/include/asm/xenomai/wrappers.h
index 28ea71d..bfff14b 100644
--- a/kernel/cobalt/arch/x86/include/asm/xenomai/wrappers.h
+++ b/kernel/cobalt/arch/x86/include/asm/xenomai/wrappers.h
@@ -24,4 +24,23 @@
 #define __get_user_inatomic __get_user
 #define __put_user_inatomic __put_user
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0)
+#include <asm/i387.h>
+#include <asm/fpu-internal.h>
+
+static inline void kernel_fpu_disable(void)
+{
+       __thread_clear_has_fpu(current);
+}
+
+static inline void kernel_fpu_enable(void)
+{
+}
+
+static inline bool kernel_fpu_disabled(void)
+{
+       return __thread_has_fpu(current) == 0 && (read_cr0() & X86_CR0_TS) == 0;
+}
+#endif /* linux < 4.1.0 */
+
 #endif /* _COBALT_X86_ASM_WRAPPERS_H */
diff --git a/kernel/cobalt/arch/x86/thread.c b/kernel/cobalt/arch/x86/thread.c
index fe7ae7b..d367d13 100644
--- a/kernel/cobalt/arch/x86/thread.c
+++ b/kernel/cobalt/arch/x86/thread.c
@@ -317,8 +317,8 @@ int xnarch_handle_fpu_fault(struct xnthread *from,
        return 1;
 }
 
-#define current_task_used_kfpu(p) \
-       (__thread_has_fpu(p) == 0 && (read_cr0() & X86_CR0_TS) == 0)
+#define current_task_used_kfpu() kernel_fpu_disabled()
+
 #define tcb_used_kfpu(t) ((t)->root_kfpu)
 
 void xnarch_leave_root(struct xnthread *root)
@@ -331,7 +331,7 @@ void xnarch_leave_root(struct xnthread *root)
        rootcb->spp = &p->thread.sp;
        rootcb->ipp = &p->thread.rip;
 #endif
-       if (current_task_used_kfpu(p) == 0) {
+       if (current_task_used_kfpu() == 0) {
                rootcb->root_kfpu = 0;
                rootcb->fpup = __thread_has_fpu(p) ? current_task_fpup : NULL;
                return;
@@ -343,6 +343,7 @@ void xnarch_leave_root(struct xnthread *root)
        x86_fpustate_ptr(&p->thread) = &rootcb->i387;
        __thread_set_has_fpu(p);
        set_stopped_child_used_math(p);
+       kernel_fpu_enable();
 }
 
 void xnarch_save_fpu(struct xnthread *thread)
@@ -387,11 +388,13 @@ void xnarch_switch_fpu(struct xnthread *from, struct 
xnthread *to)
                __thread_set_has_fpu(p);
                return;
        }
+       kernel_fpu_disable();
 
        x86_fpustate_ptr(&p->thread) = to->tcb.fpup;
-       __thread_clear_has_fpu(p);
-       if (tcb->root_used_math == 0)
+       if (tcb->root_used_math == 0) {
+               __thread_clear_has_fpu(p);
                clear_stopped_child_used_math(p);
+       }
 }
 
 void xnarch_init_root_tcb(struct xnthread *thread)


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to