fill in si_code for fpu faults
Quoted 4 lines · David Mosberger
Basically OK with me, however:
o What's the point of declaring
fp_fault_infoin a header file? It's used only in one place.
No particular reason. Fixed.
Quoted 3 lines
o
si_codeis NOT a bitmask; it makes no sense at all forfp_fault_si_code()to OR multiple values together; this makes me highly suspicious that there is a misunderstanding somewhere...
Yes, there was a misunderstanding, but I think I get it now. Fixed.
Quoted 4 lines
o Who defined
FP_SWASSTandFPE_DENORM? I don't recall seeing them in the ia64 psABI and they definitely look ia64-specific, so their names should at least be prefixed by a double-underscore (siginfo.h).
Yeah, they're ia64 specific, so I've prefixed them, but I'm not sure if they're valid from an ABI perspective. Should we just return FPE_FLTINV for those cases?
Quoted 2 lines
o If you add stuff to
asm/siginfo.h, don't forget to update glibc (insysdeps/unix/sysv/linux/ia64/bits/siginfo.h).
Ok.
Hope this is a little better.
Thanks for looking at this,
Jesse
arch/ia64/kernel/traps.c +36 -2
@@ -45,6 +45,37 @@static fpswa_interface_t *fpswa_interface; +/* +* fp fault isr.code <-> siginfo.si_code mapping +*/ +static struct _fp_fault_info { +unsigned long isr_code_bit; +int si_code;/* SIGFPE si_code */ +} fp_fault_info[] = { + {1 <<0 ,FPE_FLTINV }, + {1 <<1 , __FPE_DENORM }, + {1 <<2 ,FPE_FLTDIV }, + {1 <<3 , __FPE_SWASST }, + {1 <<4 ,FPE_FLTINV }, + {1 <<5 , __FPE_DENORM }, + {1 <<6 ,FPE_FLTDIV }, + {1 <<7 , __FPE_SWASST }, +}; + +static inline int +fp_fault_si_code (__u64 isr) +{ +int i; +int nr_entries; + nr_entries =sizeof (fp_fault_info)/sizeof (struct fp_fault_info ); + +for (i =0 ; i < nr_entries; i++) { +if (isr & fp_fault_info[i].isr_code_bit) +return fp_fault_info[i].si_code; + } +return FPE_FLTINV ;/* no code found? */ +} +void __init trap_init (void ) {
@@ -336,8 +367,9 @@ fpu_swa_count =0 ;if ((++fpu_swa_count <5 ) && !(current->thread.flags &IA64_THREAD_FPEMU_NOPRINT )) { last_time = jiffies; -printk (KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx\n" , - current->comm, current->pid, regs->cr_iip +ia64_psr (regs)->ri); +printk (KERN_WARNING "%s(%d): floating-point assist %s " , + current->comm, current->pid, fp_fault ?"fault:" :"trap" ); +printk ("ip=%016lx, isr=%16lx\n" , regs->cr_iip +ia64_psr (regs)->ri, isr); } exception = fp_emulate(fp_fault, bundle, ®s->cr_ipsr, ®s->ar_fpsr, &isr, ®s->pr,
@@ -556,6 +588,8 @@ siginfo.si_signo =SIGFPE ; siginfo.si_errno =0 ; siginfo.si_code =FPE_FLTINV ; +if (vector ==32 )/* decode fault into si_code */ + siginfo.si_code =fp_fault_si_code (isr); siginfo.si_addr = (void *) (regs->cr_iip +ia64_psr (regs)->ri); siginfo.si_flags = __ISR_VALID; siginfo.si_isr = isr;
include/asm-ia64/#fpu.h# +65 -0
65 lines not on this page · raw message
include/asm-ia64/fpu.h +5 -0
@@ -54,6 +54,11 @@ # ifndef __ASSEMBLY__ +struct fp_fault_info { + unsigned long isr_code_bit; + int si_code; /* SIGFPE si_code */ +}; + struct ia64_fpreg { union { unsigned long bits[2];
include/asm-ia64/siginfo.h +2 -0
@@ -172,6 +172,8 @@#define __FPE_DECERR (__SI_FAULT|11)/* packed decimal error */ #define __FPE_INVASC (__SI_FAULT|12)/* invalid ASCII digit */ #define __FPE_INVDEC (__SI_FAULT|13)/* invalid decimal digit */ +#define __FPE_SWASST (__SI_FAULT|14)/* software assist fault */ +#define __FPE_DENORM (__SI_FAULT|15)/* denormal/unnormal operand */ #define NSIGFPE 13/*