@@ -268,16 +268,15 @@ static void vfp_panic(char *reason, u32 inst)
268
268
/*
269
269
* Process bitmask of exception conditions.
270
270
*/
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 )
272
272
{
273
273
int si_code = 0 ;
274
274
275
275
pr_debug ("VFP: raising exceptions %08x\n" , exceptions );
276
276
277
277
if (exceptions == VFP_EXCEPTION_ERROR ) {
278
278
vfp_panic ("unhandled bounce" , inst );
279
- vfp_raise_sigfpe (FPE_FLTINV , regs );
280
- return ;
279
+ return FPE_FLTINV ;
281
280
}
282
281
283
282
/*
@@ -305,8 +304,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_
305
304
RAISE (FPSCR_OFC , FPSCR_OFE , FPE_FLTOVF );
306
305
RAISE (FPSCR_IOC , FPSCR_IOE , FPE_FLTINV );
307
306
308
- if (si_code )
309
- vfp_raise_sigfpe (si_code , regs );
307
+ return si_code ;
310
308
}
311
309
312
310
/*
@@ -352,6 +350,8 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
352
350
static void VFP_bounce (u32 trigger , u32 fpexc , struct pt_regs * regs )
353
351
{
354
352
u32 fpscr , orig_fpscr , fpsid , exceptions ;
353
+ int si_code2 = 0 ;
354
+ int si_code = 0 ;
355
355
356
356
pr_debug ("VFP: bounce: trigger %08x fpexc %08x\n" , trigger , fpexc );
357
357
@@ -397,8 +397,8 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
397
397
* unallocated VFP instruction but with FPSCR.IXE set and not
398
398
* on VFP subarch 1.
399
399
*/
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 ;
402
402
}
403
403
404
404
/*
@@ -422,14 +422,14 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
422
422
*/
423
423
exceptions = vfp_emulate_instruction (trigger , fpscr , regs );
424
424
if (exceptions )
425
- vfp_raise_exceptions (exceptions , trigger , orig_fpscr , regs );
425
+ si_code2 = vfp_raise_exceptions (exceptions , trigger , orig_fpscr );
426
426
427
427
/*
428
428
* If there isn't a second FP instruction, exit now. Note that
429
429
* the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
430
430
*/
431
431
if ((fpexc & (FPEXC_EX | FPEXC_FP2V )) != (FPEXC_EX | FPEXC_FP2V ))
432
- return ;
432
+ goto exit ;
433
433
434
434
/*
435
435
* The barrier() here prevents fpinst2 being read
@@ -441,7 +441,13 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
441
441
emulate :
442
442
exceptions = vfp_emulate_instruction (trigger , orig_fpscr , regs );
443
443
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 );
445
451
}
446
452
447
453
static void vfp_enable (void * unused )
@@ -773,6 +779,7 @@ static int vfp_support_entry(struct pt_regs *regs, u32 trigger)
773
779
* replay the instruction that trapped.
774
780
*/
775
781
fmxr (FPEXC , fpexc );
782
+ vfp_state_release ();
776
783
} else {
777
784
/* Check for synchronous or asynchronous exceptions */
778
785
if (!(fpexc & (FPEXC_EX | FPEXC_DEX ))) {
@@ -794,10 +801,10 @@ static int vfp_support_entry(struct pt_regs *regs, u32 trigger)
794
801
}
795
802
}
796
803
bounce : regs -> ARM_pc += 4 ;
804
+ /* VFP_bounce() will invoke vfp_state_release() */
797
805
VFP_bounce (trigger , fpexc , regs );
798
806
}
799
807
800
- vfp_state_release ();
801
808
return 0 ;
802
809
}
803
810
0 commit comments