Skip to contentSkip to conversation

fill in si_code for fpu faults

PATCH Jesse Barnes 1 participant 1 message Dec 12, 2002

lore
Share & tools
lore
#0 lore raw
Quoted 4 lines · David Mosberger

Basically OK with me, however:

o What's the point of declaring fp_fault_info in a header file? It's used only in one place.

No particular reason. Fixed.

Quoted 3 lines

o si_code is NOT a bitmask; it makes no sense at all for fp_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_SWASST and FPE_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 (in sysdeps/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
diff -Naur -X /home/jbarnes/dontdiff linux-2.4.19-ia64/arch/ia64/kernel/traps.c linux-2.4.19-ia64-fpswa/arch/ia64/kernel/traps.c
@@ -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, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->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
diff -Naur -X /home/jbarnes/dontdiff linux-2.4.19-ia64/include/asm-ia64/fpu.h linux-2.4.19-ia64-fpswa/include/asm-ia64/fpu.h
@@ -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
diff -Naur -X /home/jbarnes/dontdiff linux-2.4.19-ia64/include/asm-ia64/siginfo.h linux-2.4.19-ia64-fpswa/include/asm-ia64/siginfo.h
@@ -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
 
 /*