|
@@ -19,6 +19,19 @@
|
|
|
#include <asm/fpu-internal.h>
|
|
|
#include <asm/user.h>
|
|
|
|
|
|
+static DEFINE_PER_CPU(bool, in_kernel_fpu);
|
|
|
+
|
|
|
+void kernel_fpu_disable(void)
|
|
|
+{
|
|
|
+ WARN_ON(this_cpu_read(in_kernel_fpu));
|
|
|
+ this_cpu_write(in_kernel_fpu, true);
|
|
|
+}
|
|
|
+
|
|
|
+void kernel_fpu_enable(void)
|
|
|
+{
|
|
|
+ this_cpu_write(in_kernel_fpu, false);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Were we in an interrupt that interrupted kernel mode?
|
|
|
*
|
|
@@ -33,6 +46,9 @@
|
|
|
*/
|
|
|
static inline bool interrupted_kernel_fpu_idle(void)
|
|
|
{
|
|
|
+ if (this_cpu_read(in_kernel_fpu))
|
|
|
+ return false;
|
|
|
+
|
|
|
if (use_eager_fpu())
|
|
|
return __thread_has_fpu(current);
|
|
|
|
|
@@ -73,10 +89,10 @@ void __kernel_fpu_begin(void)
|
|
|
{
|
|
|
struct task_struct *me = current;
|
|
|
|
|
|
+ this_cpu_write(in_kernel_fpu, true);
|
|
|
+
|
|
|
if (__thread_has_fpu(me)) {
|
|
|
- __thread_clear_has_fpu(me);
|
|
|
__save_init_fpu(me);
|
|
|
- /* We do 'stts()' in __kernel_fpu_end() */
|
|
|
} else if (!use_eager_fpu()) {
|
|
|
this_cpu_write(fpu_owner_task, NULL);
|
|
|
clts();
|
|
@@ -86,19 +102,16 @@ EXPORT_SYMBOL(__kernel_fpu_begin);
|
|
|
|
|
|
void __kernel_fpu_end(void)
|
|
|
{
|
|
|
- if (use_eager_fpu()) {
|
|
|
- /*
|
|
|
- * For eager fpu, most the time, tsk_used_math() is true.
|
|
|
- * Restore the user math as we are done with the kernel usage.
|
|
|
- * At few instances during thread exit, signal handling etc,
|
|
|
- * tsk_used_math() is false. Those few places will take proper
|
|
|
- * actions, so we don't need to restore the math here.
|
|
|
- */
|
|
|
- if (likely(tsk_used_math(current)))
|
|
|
- math_state_restore();
|
|
|
- } else {
|
|
|
+ struct task_struct *me = current;
|
|
|
+
|
|
|
+ if (__thread_has_fpu(me)) {
|
|
|
+ if (WARN_ON(restore_fpu_checking(me)))
|
|
|
+ drop_init_fpu(me);
|
|
|
+ } else if (!use_eager_fpu()) {
|
|
|
stts();
|
|
|
}
|
|
|
+
|
|
|
+ this_cpu_write(in_kernel_fpu, false);
|
|
|
}
|
|
|
EXPORT_SYMBOL(__kernel_fpu_end);
|
|
|
|