diff mbox

Kernel panic on FPU instruction without FPU present

Message ID 20130123203325.1e330a9a@bever
State Rejected
Delegated to: David Miller
Headers show

Commit Message

Joris van Rantwijk Jan. 23, 2013, 7:33 p.m. UTC
Hello,

I'm running Linux on a LEON3 SparcV8 without floating point unit
present (the PSR_EF bit is hardwired to 0).

I noticed that I can easily cause a kernel panic by running a
user-mode application with an FPU instruction in it.

The FPU instruction traps to do_fpd_trap().
The kernel then tries to enable the FPU by setting PSR_EF and performs
an FPU context switch. During the FPU context switch, the kernel itself
executes an FPU instruction, which jumps to do_fpd_trap() and then the
system dies.

I prepared a patch which modifies do_fpd_trap() to be more graceful
on machines that can not enable PSR_EF.
Tested on Linux 3.7.1 and Linux 3.8-rc4.

Can anyone here decide if this is the right approach and help me to
get this fixed in the kernel?

Thanks, Joris.


--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

David Miller Jan. 23, 2013, 8:50 p.m. UTC | #1
I don't think we're going to support chips that lack an FPU,
sorry.

You can't even run the simplest things like the python interpreter
without FPU support, the first thing it does during initialization
is do a floating point square root.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Joris van Rantwijk Jan. 23, 2013, 10:01 p.m. UTC | #2
On 2013-01-23, David Miller wrote:
> I don't think we're going to support chips that lack an FPU,
> sorry.

Ok, fair enough.
The kernel has explicit support for the LEON3 in several places, and I
automatically assumed that it would aim to support all possible
configurations. But I guess it makes sense to draw the line somewhere,
especially if all other SPARC variants have built-in FPUs.

> You can't even run the simplest things like the python interpreter
> without FPU support, the first thing it does during initialization
> is do a floating point square root.

You can of course still run such things as long as all of userland is
compiled with a toolchain that emulates floating point on compiler
level (i.e. GCC --with-float=soft). This is a fairly normal way to
build software for LEON3.

Thanks, Joris.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Julian Calaby Jan. 23, 2013, 10:02 p.m. UTC | #3
Hi David,

On Thu, Jan 24, 2013 at 7:50 AM, David Miller <davem@davemloft.net> wrote:
>
> I don't think we're going to support chips that lack an FPU,
> sorry.
>
> You can't even run the simplest things like the python interpreter
> without FPU support, the first thing it does during initialization
> is do a floating point square root.

As Joris said, you can compile software to do their floating point
calculations in software - I believe the option is --no-fpu in gcc -
however the entire toolchain needs to be compiled with support for
this.
 - http://gcc.gnu.org/wiki/Software_floating_point
 - http://gcc.gnu.org/onlinedocs/gcc/SPARC-Options.html
 - http://stackoverflow.com/questions/1018638/using-software-floating-point-on-x86-linux

Also, ignoring the massive amount of work this would take, would it be
possible to handle the trap by hooking into the kernel's soft float
implementation instead?

Personally, I don't see any issue with printing a scary message and
killing the task if it tries to do floating point on a system without
it.

Thanks,
diff mbox

Patch

diff -U 5 -urN linux-3.7.1/arch/sparc/kernel/traps_32.c linux-3.7.1-sparcfp/arch/sparc/kernel/traps_32.c
--- linux-3.7.1/arch/sparc/kernel/traps_32.c	2012-12-17 20:14:54.000000000 +0100
+++ linux-3.7.1-sparcfp/arch/sparc/kernel/traps_32.c	2013-01-20 19:38:02.616017770 +0100
@@ -183,10 +183,24 @@ 
 	/* Sanity check... */
 	if(psr & PSR_PS)
 		die_if_kernel("Kernel gets FloatingPenguinUnit disabled trap", regs);
 
 	put_psr(get_psr() | PSR_EF);    /* Allow FPU ops. */
+
+	if ((get_psr() & PSR_EF) == 0) {
+		/* No FPU present. Do not kill the kernel in this case. */
+		siginfo_t info;
+		printk(KERN_INFO "%s[%d]: no FPU present PC=%08lx\n", current->comm, task_pid_nr(current), pc);
+		info.si_signo = SIGFPE;
+		info.si_errno = 0;
+		info.si_addr = (void __user *)pc;
+		info.si_trapno = 0;
+		info.si_code = __SI_FAULT;
+		force_sig_info(SIGFPE, &info, current);
+		return;
+	}
+
 	regs->psr |= PSR_EF;
 #ifndef CONFIG_SMP
 	if(last_task_used_math == current)
 		return;
 	if(last_task_used_math) {