diff options
-rw-r--r-- | arch/arm/vfp/vfphw.S | 5 | ||||
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 20 |
2 files changed, 25 insertions, 0 deletions
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 8d10dc8a1e17..3e5d3115a2a6 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
@@ -78,6 +78,11 @@ | |||
78 | ENTRY(vfp_support_entry) | 78 | ENTRY(vfp_support_entry) |
79 | DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 | 79 | DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 |
80 | 80 | ||
81 | ldr r3, [sp, #S_PSR] @ Neither lazy restore nor FP exceptions | ||
82 | and r3, r3, #MODE_MASK @ are supported in kernel mode | ||
83 | teq r3, #USR_MODE | ||
84 | bne vfp_kmode_exception @ Returns through lr | ||
85 | |||
81 | VFPFMRX r1, FPEXC @ Is the VFP enabled? | 86 | VFPFMRX r1, FPEXC @ Is the VFP enabled? |
82 | DBGSTR1 "fpexc %08x", r1 | 87 | DBGSTR1 "fpexc %08x", r1 |
83 | tst r1, #FPEXC_EN | 88 | tst r1, #FPEXC_EN |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 791993aed75a..7620831a0c66 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -648,6 +648,26 @@ static int vfp_hotplug(struct notifier_block *b, unsigned long action, | |||
648 | return NOTIFY_OK; | 648 | return NOTIFY_OK; |
649 | } | 649 | } |
650 | 650 | ||
651 | void vfp_kmode_exception(void) | ||
652 | { | ||
653 | /* | ||
654 | * If we reach this point, a floating point exception has been raised | ||
655 | * while running in kernel mode. If the NEON/VFP unit was enabled at the | ||
656 | * time, it means a VFP instruction has been issued that requires | ||
657 | * software assistance to complete, something which is not currently | ||
658 | * supported in kernel mode. | ||
659 | * If the NEON/VFP unit was disabled, and the location pointed to below | ||
660 | * is properly preceded by a call to kernel_neon_begin(), something has | ||
661 | * caused the task to be scheduled out and back in again. In this case, | ||
662 | * rebuilding and running with CONFIG_DEBUG_ATOMIC_SLEEP enabled should | ||
663 | * be helpful in localizing the problem. | ||
664 | */ | ||
665 | if (fmrx(FPEXC) & FPEXC_EN) | ||
666 | pr_crit("BUG: unsupported FP instruction in kernel mode\n"); | ||
667 | else | ||
668 | pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n"); | ||
669 | } | ||
670 | |||
651 | /* | 671 | /* |
652 | * VFP support code initialisation. | 672 | * VFP support code initialisation. |
653 | */ | 673 | */ |