Skip to content

Commit

Permalink
ARM: be strict about FP exceptions in kernel mode
Browse files Browse the repository at this point in the history
The support code in vfp_support_entry does not care whether the
exception that caused it to be invoked occurred in kernel mode or
in user mode. However, neither condition that could trigger this
exception (lazy restore and VFP bounce to support code) is
currently allowable in kernel mode.

In either case, print a message describing the condition before
letting the undefined instruction handler run its course and trigger
an oops.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Nicolas Pitre <nico@linaro.org>
  • Loading branch information
Ard Biesheuvel committed Jul 8, 2013
1 parent 0773d73 commit ab3da15
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
5 changes: 5 additions & 0 deletions arch/arm/vfp/vfphw.S
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@
ENTRY(vfp_support_entry)
DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10

ldr r3, [sp, #S_PSR] @ Neither lazy restore nor FP exceptions
and r3, r3, #MODE_MASK @ are supported in kernel mode
teq r3, #USR_MODE
bne vfp_kmode_exception @ Returns through lr

VFPFMRX r1, FPEXC @ Is the VFP enabled?
DBGSTR1 "fpexc %08x", r1
tst r1, #FPEXC_EN
Expand Down
20 changes: 20 additions & 0 deletions arch/arm/vfp/vfpmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,26 @@ static int vfp_hotplug(struct notifier_block *b, unsigned long action,
return NOTIFY_OK;
}

void vfp_kmode_exception(void)
{
/*
* If we reach this point, a floating point exception has been raised
* while running in kernel mode. If the NEON/VFP unit was enabled at the
* time, it means a VFP instruction has been issued that requires
* software assistance to complete, something which is not currently
* supported in kernel mode.
* If the NEON/VFP unit was disabled, and the location pointed to below
* is properly preceded by a call to kernel_neon_begin(), something has
* caused the task to be scheduled out and back in again. In this case,
* rebuilding and running with CONFIG_DEBUG_ATOMIC_SLEEP enabled should
* be helpful in localizing the problem.
*/
if (fmrx(FPEXC) & FPEXC_EN)
pr_crit("BUG: unsupported FP instruction in kernel mode\n");
else
pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n");
}

/*
* VFP support code initialisation.
*/
Expand Down

0 comments on commit ab3da15

Please sign in to comment.