@@ -268,16 +268,15 @@ static void vfp_panic(char *reason, u32 inst)
268268/*
269269 * Process bitmask of exception conditions.
270270 */
271- static void vfp_raise_exceptions (u32 exceptions , u32 inst , u32 fpscr , struct pt_regs * regs )
271+ static int vfp_raise_exceptions (u32 exceptions , u32 inst , u32 fpscr )
272272{
273273 int si_code = 0 ;
274274
275275 pr_debug ("VFP: raising exceptions %08x\n" , exceptions );
276276
277277 if (exceptions == VFP_EXCEPTION_ERROR ) {
278278 vfp_panic ("unhandled bounce" , inst );
279- vfp_raise_sigfpe (FPE_FLTINV , regs );
280- return ;
279+ return FPE_FLTINV ;
281280 }
282281
283282 /*
@@ -305,8 +304,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_
305304 RAISE (FPSCR_OFC , FPSCR_OFE , FPE_FLTOVF );
306305 RAISE (FPSCR_IOC , FPSCR_IOE , FPE_FLTINV );
307306
308- if (si_code )
309- vfp_raise_sigfpe (si_code , regs );
307+ return si_code ;
310308}
311309
312310/*
@@ -352,6 +350,8 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
352350static void VFP_bounce (u32 trigger , u32 fpexc , struct pt_regs * regs )
353351{
354352 u32 fpscr , orig_fpscr , fpsid , exceptions ;
353+ int si_code2 = 0 ;
354+ int si_code = 0 ;
355355
356356 pr_debug ("VFP: bounce: trigger %08x fpexc %08x\n" , trigger , fpexc );
357357
@@ -397,8 +397,8 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
397397 * unallocated VFP instruction but with FPSCR.IXE set and not
398398 * on VFP subarch 1.
399399 */
400- vfp_raise_exceptions (VFP_EXCEPTION_ERROR , trigger , fpscr , regs );
401- return ;
400+ si_code = vfp_raise_exceptions (VFP_EXCEPTION_ERROR , trigger , fpscr );
401+ goto exit ;
402402 }
403403
404404 /*
@@ -422,14 +422,14 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
422422 */
423423 exceptions = vfp_emulate_instruction (trigger , fpscr , regs );
424424 if (exceptions )
425- vfp_raise_exceptions (exceptions , trigger , orig_fpscr , regs );
425+ si_code2 = vfp_raise_exceptions (exceptions , trigger , orig_fpscr );
426426
427427 /*
428428 * If there isn't a second FP instruction, exit now. Note that
429429 * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
430430 */
431431 if ((fpexc & (FPEXC_EX | FPEXC_FP2V )) != (FPEXC_EX | FPEXC_FP2V ))
432- return ;
432+ goto exit ;
433433
434434 /*
435435 * The barrier() here prevents fpinst2 being read
@@ -441,7 +441,13 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
441441 emulate :
442442 exceptions = vfp_emulate_instruction (trigger , orig_fpscr , regs );
443443 if (exceptions )
444- vfp_raise_exceptions (exceptions , trigger , orig_fpscr , regs );
444+ si_code = vfp_raise_exceptions (exceptions , trigger , orig_fpscr );
445+ exit :
446+ vfp_state_release ();
447+ if (si_code2 )
448+ vfp_raise_sigfpe (si_code2 , regs );
449+ if (si_code )
450+ vfp_raise_sigfpe (si_code , regs );
445451}
446452
447453static void vfp_enable (void * unused )
@@ -773,6 +779,7 @@ static int vfp_support_entry(struct pt_regs *regs, u32 trigger)
773779 * replay the instruction that trapped.
774780 */
775781 fmxr (FPEXC , fpexc );
782+ vfp_state_release ();
776783 } else {
777784 /* Check for synchronous or asynchronous exceptions */
778785 if (!(fpexc & (FPEXC_EX | FPEXC_DEX ))) {
@@ -794,10 +801,10 @@ static int vfp_support_entry(struct pt_regs *regs, u32 trigger)
794801 }
795802 }
796803bounce : regs -> ARM_pc += 4 ;
804+ /* VFP_bounce() will invoke vfp_state_release() */
797805 VFP_bounce (trigger , fpexc , regs );
798806 }
799807
800- vfp_state_release ();
801808 return 0 ;
802809}
803810
0 commit comments