Skip to content

i387: ptrace breaks the lazy-fpu-restore logic

Oleg Nesterov lkml 1 version In review

Get series with b4
b4 am [email protected]

Versions newest first

  1. v1 Latest1 patch 2 repliesIn review

Patches in v1 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/1i387: ptrace breaks the lazy-fpu-restore logicarch/x86/kernel/i387.c+1 -02 replies

Reviews trailers per patch

No Reviewed-by, Acked-by or Tested-by trailers for v1 yet.

Read the v1 thread

Cover letter [PATCH 0/1] i387: ptrace breaks the lazy-fpu-restore logic
Quoted 7 lines · Linus Torvalds

Put another way: I do think it would be a good idea to do the "reset last_cpu" in copy_thread() too. It doesn't really cost us anything, and it's cleaner to always just make sure that last_cpu is "valid" (even if the fpu_owner_task is *also* used to invalidate it, and even if we never use the lazy restore if fpu_counter is zero and thus fpu.preload isn't set).

Yes, this was my thinking too, and initially I was going to include this change into this patch. But lets do it separately.

I feel we need some cleanups. For example, it seems that flush_thread() can do this too, although in this case we can rely on __thread_fpu_end() which clears fpu_owner_task.

So I am just sending your one-liner, and according to my testing it fixes the problem.

And A couple of off-topic questions...

Why unlazy_fpu() clears ->fpu_counter? Afaics, this doesn't make sense and unneeded.

And it is not clear to me why init_fpu() does unlazy_fpu(), afaics tsk_used_math() "tsk == current" is only possible if this task dumps the core.

arch_dup_task_struct() checks fpu_allocated(), this doesn't look exactly right to me. Suppose that a task without PF_USED_MATH uses FPU only once in the signal handler. If it forks after that, we allocate and copy fpu->state for no reason. IOW, we probably should check tsk_used_math() instead, but do memzero(&dst->thread.fpu) unconditionally. And perhaps this memzero() deserves a helper which can set .last_cpu = -1, and this is what copy_thread() should call.

OTOH, this reminds me, a long ago I noticed by accident that all threads on the testing machine have PF_USED_MATH set. IIRC, This is because /sbin/init does memset or memcpy and glibc uses xmm for this. Not that I really suggest this, but perhaps prctl(PR_DROP_FPU) makes some sense.

Oleg.