[PATCH 1/2 v2] UBUNTU: Fix the VFP handling on the Feroceon CPU

Brad Figg brad.figg at canonical.com
Wed Mar 11 18:42:27 GMT 2009

This CPU generates synchronous VFP exceptions in a non-standard way -the
FPEXC.EX bit set but without the FPSCR.IXE bit being set like in the VFP
subarchitecture 1 or just the FPEXC.DEX bit like in VFP subarchitecture
2. The main problem is that the faulty instruction will be re-executed
indefinitely without being emulated. This patch ensures that the
VFP exception is treated as synchronous.

Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Brad Figg <brad.figg at canonical.com>
 arch/arm/vfp/vfphw.S     |    4 ++++
 arch/arm/vfp/vfpmodule.c |    2 ++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index a62dcf7..2da59a3 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -100,10 +100,12 @@ ENTRY(vfp_support_entry)
 	beq	no_old_VFP_process
 	VFPFSTMIA r4, r5		@ save the working registers
 	VFPFMRX	r5, FPSCR		@ current status
 	tst	r1, #FPEXC_EX		@ is there additional state to save?
 	VFPFMRX	r6, FPINST, NE		@ FPINST (only if FPEXC.EX is set)
 	tstne	r1, #FPEXC_FP2V		@ is there an FPINST2 to read?
 	VFPFMRX	r8, FPINST2, NE		@ FPINST2 if needed (and present)
 	stmia	r4, {r1, r5, r6, r8}	@ save FPEXC, FPSCR, FPINST, FPINST2
 					@ and point r4 at the word at the
 					@ start of the register dump
@@ -116,10 +118,12 @@ no_old_VFP_process:
 	VFPFLDMIA r10, r5		@ reload the working registers while
 					@ FPEXC is in a safe state
 	ldmia	r10, {r1, r5, r6, r8}	@ load FPEXC, FPSCR, FPINST, FPINST2
 	tst	r1, #FPEXC_EX		@ is there additional state to restore?
 	VFPFMXR	FPINST, r6, NE		@ restore FPINST (only if FPEXC.EX is set)
 	tstne	r1, #FPEXC_FP2V		@ is there an FPINST2 to write?
 	VFPFMXR	FPINST2, r8, NE		@ FPINST2 if needed (and present)
 	VFPFMXR	FPSCR, r5		@ restore status

diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index c0d2c9b..606283f 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -253,12 +253,14 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)

 	if (fpexc & FPEXC_EX) {
 		 * Asynchronous exception. The instruction is read from FPINST
 		 * and the interrupted instruction has to be restarted.
 		trigger = fmrx(FPINST);
 		regs->ARM_pc -= 4;
 	} else if (!(fpexc & FPEXC_DEX)) {
 		 * Illegal combination of bits. It can be caused by an

More information about the kernel-team mailing list