linux-mips
[Top] [All Lists]

Re: fpu_emulator can lose fpu on get_user/put_user

To: jsun@junsun.net
Subject: Re: fpu_emulator can lose fpu on get_user/put_user
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Tue, 12 Oct 2004 19:11:54 +0900 (JST)
Cc: linux-mips@linux-mips.org, ralf@linux-mips.org
In-reply-to: <20041011165424.GA28667@gateway.junsun.net>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <20041008194514.GB31533@gateway.junsun.net> <20041009.233810.74756865.anemo@mba.ocn.ne.jp> <20041011165424.GA28667@gateway.junsun.net>
Sender: linux-mips-bounce@linux-mips.org
>>>>> On Mon, 11 Oct 2004 09:54:24 -0700, Jun Sun <jsun@junsun.net> said:
jsun> I actually don't see which approach is more "simple and robust".

jsun> In terms of being simple, allowing kernel mode FPU trap is
jsun> definitely simpler.

jsun> If you can't find any pitfalls of this approach it is actually
jsun> robust.  The new FPU code is already greatly simplified.  It is
jsun> possible kernel FPU trap is not that evil anymore (assuming
jsun> kernel continues voluntarily not using FPU).

Hmm... OK, I agree enabling FPU trap in kernel seems simple.  I tried
it today but it did not work unfortunately.  Just modifying a
following line in traps.c was not enough.

        die_if_kernel("do_cpu invoked from kernel context!", regs);

One point I found is do_cpu() must enable CU1 bit in pt_regs also.
Another problem is that resume(), own_fpu() and lose_fpu() manipulate
CU1 bit in only first level kernel stack (KSTK_STATUS(current)).
current->thread.cp0_status may be manipulated also.  Modifying
resume() looks too dangerous to me.

Anyway, in math-emu case, we should call lose_fpu() BEFORE running the
emulator.  Since the emulator never use real FPU, we naturally call
own_fpu() AFTER the returning from the emulator.  It's simple.
Enabling kernel FPU trap is not needed.


>> It is safe?  get_user/put_user will fail if preempt disabled.  Excerpt
>> from do_page_fault:
>> 
>>      /*
>>       * If we're in an interrupt or have no user
>>       * context, we must not take the fault..
>>       */
>>      if (in_atomic() || !mm)
>>              goto bad_area_nosemaphore;

jsun> It should be safe.  This might be a bug in kernel.  I bet
jsun> in_atomic() is "in_interrupt()" in older version of the code,
jsun> which seems to be the correct code.  When you diable preemption
jsun> you still have a process context.

But many archs have above check in do_page_fault() long time (since
2.5.32 at i386).  Are these all broken?


jsun> BTW, have you thought about possibly the third approach, which
jsun> is to somehow isolate the code segment where get_user/put_user
jsun> could cause page faults and then make sure all FPU manipulations
jsun> will succeed?

I took this approach to fix sigcontext problem.  Please look at
signal.c in my patch.

Thank you for quick comments.

---
Atsushi Nemoto

<Prev in Thread] Current Thread [Next in Thread>