Skip to content

Commit

Permalink
i387: fix up some fpu_counter confusion
Browse files Browse the repository at this point in the history
This makes sure we clear the FPU usage counter for newly created tasks,
just so that we start off in a known state (for example, don't try to
preload the FPU state on the first task switch etc).

It also fixes a thinko in when we increment the fpu_counter at task
switch time, introduced by commit 34ddc81 ("i387: re-introduce FPU
state preloading at context switch time").  We should increment the
*new* task fpu_counter, not the old task, and only if we decide to use
that state (whether lazily or preloaded).

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Linus Torvalds committed Feb 20, 2012
1 parent b01543d commit cea20ca
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 1 deletion.
3 changes: 2 additions & 1 deletion arch/x86/include/asm/i387.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,17 +348,18 @@ static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct ta
if (__save_init_fpu(old))
fpu_lazy_state_intact(old);
__thread_clear_has_fpu(old);
old->fpu_counter++;

/* Don't change CR0.TS if we just switch! */
if (fpu.preload) {
new->fpu_counter++;
__thread_set_has_fpu(new);
prefetch(new->thread.fpu.state);
} else
stts();
} else {
old->fpu_counter = 0;
if (fpu.preload) {
new->fpu_counter++;
if (fpu_lazy_restore(new))
fpu.preload = 0;
else
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,

task_user_gs(p) = get_user_gs(regs);

p->fpu_counter = 0;
p->thread.io_bitmap_ptr = NULL;
tsk = current;
err = -ENOMEM;
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,

set_tsk_thread_flag(p, TIF_FORK);

p->fpu_counter = 0;
p->thread.io_bitmap_ptr = NULL;

savesegment(gs, p->thread.gsindex);
Expand Down

0 comments on commit cea20ca

Please sign in to comment.