Index: kernel/arch/arm32/include/fpu_context.h
===================================================================
--- kernel/arch/arm32/include/fpu_context.h	(revision e5c8bc6db05856c90d811bc6a138f38da3efea6f)
+++ kernel/arch/arm32/include/fpu_context.h	(revision 0237380b1b5452568e8987b11d3697ee674830fe)
@@ -44,9 +44,8 @@
 
 /* ARM Architecture reference manual, p B-1529.
- * We don't enable EX bit so max 32 64bit regs are stored (+2 control regs)
  */
 typedef struct {
+	uint32_t fpexc;
 	uint32_t fpuscr;
-	uint32_t fpuexc;
 	uint32_t s[64];
 } fpu_context_t;
@@ -54,4 +53,6 @@
 void fpu_setup(void);
 
+bool handle_if_fpu_exception(void);
+
 #endif
 
Index: kernel/arch/arm32/src/exception.c
===================================================================
--- kernel/arch/arm32/src/exception.c	(revision e5c8bc6db05856c90d811bc6a138f38da3efea6f)
+++ kernel/arch/arm32/src/exception.c	(revision 0237380b1b5452568e8987b11d3697ee674830fe)
@@ -167,10 +167,8 @@
 static void undef_insn_exception(unsigned int exc_no, istate_t *istate)
 {
-#ifdef CONFIG_FPU_LAZY
-	scheduler_fpu_lazy_request();
-#else
-	fault_if_from_uspace(istate, "Undefined instruction.");
-	panic_badtrap(istate, exc_no, "Undefined instruction.");
-#endif
+	if (!handle_if_fpu_exception()) {
+		fault_if_from_uspace(istate, "Undefined instruction.");
+		panic_badtrap(istate, exc_no, "Undefined instruction.");
+	}
 }
 
Index: kernel/arch/arm32/src/fpu_context.c
===================================================================
--- kernel/arch/arm32/src/fpu_context.c	(revision e5c8bc6db05856c90d811bc6a138f38da3efea6f)
+++ kernel/arch/arm32/src/fpu_context.c	(revision 0237380b1b5452568e8987b11d3697ee674830fe)
@@ -47,8 +47,31 @@
 	FPU_VFPv1 = 0x00,
 	FPU_VFPv2_COMMONv1 = 0x01,
-	FPU_VFPv3_COMMONv2 = 0x02, /* Check MVFR0 and MVFR 1*/
-	FPU_VFPv3_NOTRAP = 0x3, /* Does not support trap */
-	FPU_VFPv3 = 0x4,
+	FPU_VFPv3_COMMONv2 = 0x02,
+	FPU_VFPv3_NO_COMMON = 0x3, /* Does not support trap */
+	FPU_VFPv3_COMMONv3 = 0x4,
 };
+
+enum {
+	FPEXC_ENABLED_FLAG = 0x40000000,
+	FPEXC_EX_FLAG = 0x80000000,
+};
+
+static inline uint32_t fpexc_read()
+{
+	uint32_t reg;
+	asm volatile (
+		"vmrs %0, fpexc\n"
+		:"=r" (reg)::
+	);
+	return reg;
+}
+
+static inline void fpexc_write(uint32_t val)
+{
+	asm volatile (
+		"vmsr fpexc, %0\n"
+		::"r" (val):
+	);
+}
 
 static void (*save_context)(fpu_context_t *ctx);
@@ -62,4 +85,6 @@
 {
 	asm volatile (
+		"vmrs r1, fpexc\n"
+		"stmia %0!, {r1}\n"
 		"vmrs r1, fpscr\n"
 		"stmia %0!, {r1}\n"
@@ -76,4 +101,6 @@
 {
 	asm volatile (
+		"ldmia %0!, {r1}\n"
+		"vmsr fpexc, r1\n"
 		"ldmia %0!, {r1}\n"
 		"vmsr fpscr, r1\n"
@@ -90,4 +117,6 @@
 {
 	asm volatile (
+		"vmrs r1, fpexc\n"
+		"stmia %0!, {r1}\n"
 		"vmrs r1, fpscr\n"
 		"stmia %0!, {r1}\n"
@@ -104,4 +133,6 @@
 {
 	asm volatile (
+		"ldmia %0!, {r1}\n"
+		"vmsr fpexc, r1\n"
 		"ldmia %0!, {r1}\n"
 		"vmsr fpscr, r1\n"
@@ -118,4 +149,6 @@
 {
 	asm volatile (
+		"vmrs r1, fpexc\n"
+		"stmia %0!, {r1}\n"
 		"vmrs r1, fpscr\n"
 		"stmia %0!, {r1}\n"
@@ -133,4 +166,6 @@
 {
 	asm volatile (
+		"ldmia %0!, {r1}\n"
+		"vmsr fpexc, r1\n"
 		"ldmia %0!, {r1}\n"
 		"vmsr fpscr, r1\n"
@@ -143,4 +178,6 @@
 void fpu_init(void)
 {
+	/* Clear all fpu flags */
+	fpexc_write(0);
 	fpu_enable();
 }
@@ -150,5 +187,5 @@
 	uint32_t fpsid = 0;
 	asm volatile (
-		"vmrs %0,fpsid\n"
+		"vmrs %0, fpsid\n"
 		:"=r"(fpsid)::
 	);
@@ -170,6 +207,6 @@
 		break;
 	case FPU_VFPv3_COMMONv2:
-	case FPU_VFPv3_NOTRAP:
-	case FPU_VFPv3: {
+	case FPU_VFPv3_NO_COMMON:
+	case FPU_VFPv3_COMMONv3: {
 		uint32_t mvfr0 = 0;
 		asm volatile (
@@ -179,11 +216,11 @@
 		/* See page B4-1637 */
 		if ((mvfr0 & 0xf) == 0x1) {
+			printf("Detected VFPv3+ with 16 regs\n");
+			save_context = fpu_context_save_d16;
+			restore_context = fpu_context_restore_d16;
+		} else {
 			printf("Detected VFPv3+ with 32 regs\n");
 			save_context = fpu_context_save_d32;
 			restore_context = fpu_context_restore_d32;
-		} else {
-			printf("Detected VFPv3+ with 16 regs\n");
-			save_context = fpu_context_save_d16;
-			restore_context = fpu_context_restore_d16;
 		}
 		break;
@@ -193,12 +230,23 @@
 }
 
+bool handle_if_fpu_exception(void)
+{
+	const uint32_t fpexc = fpexc_read();
+	if (fpexc & FPEXC_ENABLED_FLAG) {
+		printf("FPU exception with FPU on\n");
+		return false;
+	}
+#ifdef CONFIG_FPU_LAZY
+	scheduler_fpu_lazy_request();
+	return true;
+#else
+	return false;
+#endif
+}
+
 void fpu_enable(void)
 {
 	/* Enable FPU instructions */
-	asm volatile (
-		"ldr r1, =0x40000000\n"
-		"vmsr fpexc, r1\n"
-		::: "r1"
-	);
+	fpexc_write(fpexc_read() | FPEXC_ENABLED_FLAG);
 }
 
@@ -206,9 +254,5 @@
 {
 	/* Disable FPU instructions */
-	asm volatile (
-		"ldr r1, =0x00000000\n"
-		"vmsr fpexc, r1\n"
-		::: "r1"
-	);
+	fpexc_write(fpexc_read() & ~FPEXC_ENABLED_FLAG);
 }
 
