From 6a5fe8952bd676baf382d14df21e7b32b5d8943e Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Fri, 6 Feb 2015 15:02:04 -0500 Subject: x86/fpu: Use task_disable_lazy_fpu_restore() helper Replace magic assignments of fpu.last_cpu = ~0 with more explicit task_disable_lazy_fpu_restore() calls. Signed-off-by: Rik van Riel Cc: Oleg Nesterov Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1423252925-14451-8-git-send-email-riel@redhat.com Signed-off-by: Borislav Petkov --- arch/x86/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86/kernel/process.c') diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index e127ddaa2d5a..ce8b10351e28 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -68,8 +68,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) dst->thread.fpu_counter = 0; dst->thread.fpu.has_fpu = 0; - dst->thread.fpu.last_cpu = ~0; dst->thread.fpu.state = NULL; + task_disable_lazy_fpu_restore(dst); if (tsk_used_math(src)) { int err = fpu_alloc(&dst->thread.fpu); if (err) -- cgit v1.2.1 From 110d7f7513bbb916b8654da9e2973ac5bed929a9 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 19 Jan 2015 19:52:12 +0100 Subject: x86/fpu: Don't abuse FPU in kernel threads if use_eager_fpu() AFAICS, there is no reason why kernel threads should have FPU context even if use_eager_fpu() == T. Now that interrupted_kernel_fpu_idle() does not check __thread_has_fpu() in the use_eager_fpu() case, we can remove the init_fpu() code from eager_fpu_init() and change flush_thread() called by do_execve() to initialize FPU. Note: of course, the change in flush_thread() is horrible and must be cleanuped. We need the new helper, and flush_thread() should return the error if init_fpu() fails. Signed-off-by: Oleg Nesterov Reviewed-by: Rik van Riel Cc: Linus Torvalds Cc: Suresh Siddha Cc: Andy Lutomirski Link: http://lkml.kernel.org/r/20150119185212.GD16427@redhat.com Signed-off-by: Borislav Petkov --- arch/x86/kernel/process.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/x86/kernel/process.c') diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index ce8b10351e28..83480373a642 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -130,6 +130,7 @@ void flush_thread(void) flush_ptrace_hw_breakpoint(tsk); memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); + drop_init_fpu(tsk); /* * Free the FPU state for non xsave platforms. They get reallocated @@ -137,6 +138,12 @@ void flush_thread(void) */ if (!use_eager_fpu()) free_thread_xstate(tsk); + else if (!used_math()) { + /* kthread execs. TODO: cleanup this horror. */ + if (WARN_ON(init_fpu(current))) + force_sig(SIGKILL, current); + math_state_restore(); + } } static void hard_disable_TSC(void) -- cgit v1.2.1 From 9cb6ce823bbd1adbe15e30bd1435c84c2e271767 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 11 Mar 2015 18:34:49 +0100 Subject: x86/fpu: Use restore_init_xstate() instead of math_state_restore() on kthread exec Change flush_thread() to do user_fpu_begin() and restore_init_xstate() instead of math_state_restore(). Note: "TODO: cleanup this horror" is still valid. We do not need init_fpu() at all, we only need fpu_alloc() and memset(0). But this needs other changes, in particular user_fpu_begin() should set used_math(). Signed-off-by: Oleg Nesterov Signed-off-by: Borislav Petkov Cc: Andy Lutomirski Cc: Dave Hansen Cc: Fenghua Yu Cc: Linus Torvalds Cc: Pekka Riikonen Cc: Quentin Casasnovas Cc: Rik van Riel Cc: Suresh Siddha Link: http://lkml.kernel.org/r/20150311173449.GE5032@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/process.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/x86/kernel/process.c') diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index dcaf4b00d0b4..6b058296a456 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -143,7 +143,8 @@ void flush_thread(void) /* kthread execs. TODO: cleanup this horror. */ if (WARN_ON(init_fpu(current))) force_sig(SIGKILL, current); - math_state_restore(); + user_fpu_begin(); + restore_init_xstate(); } } -- cgit v1.2.1 From f893959b0898bd876673adbeb6798bdf25c034d7 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 13 Mar 2015 18:30:30 +0100 Subject: x86/fpu: Don't abuse drop_init_fpu() in flush_thread() flush_thread() -> drop_init_fpu() is suboptimal and confusing. It does drop_fpu() or restore_init_xstate() depending on !use_eager_fpu(). But flush_thread() too checks eagerfpu right after that, and if it is true then restore_init_xstate() just burns CPU for no reason. We are going to load init_xstate_buf again after we set used_math()/user_has_fpu(), until then the FPU state can't survive after switch_to(). Remove it, and change the "if (!use_eager_fpu())" to call drop_fpu(). While at it, clean up the tsk/current usage. Signed-off-by: Oleg Nesterov Signed-off-by: Borislav Petkov Cc: Andy Lutomirski Cc: Dave Hansen Cc: Fenghua Yu Cc: Linus Torvalds Cc: Pekka Riikonen Cc: Quentin Casasnovas Cc: Rik van Riel Cc: Suresh Siddha Link: http://lkml.kernel.org/r/20150313173030.GA31217@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/process.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'arch/x86/kernel/process.c') diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 6b058296a456..1d2ebadba7ac 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -132,17 +132,14 @@ void flush_thread(void) flush_ptrace_hw_breakpoint(tsk); memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); - drop_init_fpu(tsk); - /* - * Free the FPU state for non xsave platforms. They get reallocated - * lazily at the first use. - */ - if (!use_eager_fpu()) + if (!use_eager_fpu()) { + /* FPU state will be reallocated lazily at the first use. */ + drop_fpu(tsk); free_thread_xstate(tsk); - else if (!used_math()) { + } else if (!used_math()) { /* kthread execs. TODO: cleanup this horror. */ - if (WARN_ON(init_fpu(current))) - force_sig(SIGKILL, current); + if (WARN_ON(init_fpu(tsk))) + force_sig(SIGKILL, tsk); user_fpu_begin(); restore_init_xstate(); } -- cgit v1.2.1