[parisc-linux] traps.c 2.4 alignement [was: 2.6.0-test6-pa6 on b2k finaly crash]
Joel Soete
soete.joel@tiscali.be
Sun, 05 Oct 2003 15:06:48 +0000
This is a multi-part message in MIME format.
--------------030403020700060302040201
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Joel Soete wrote:
>I am also happy that with 2.6.0-test6-pa6 b2k crash because it is a long
>time that I try to obtain a relevant info (even toc do not help until now).
>And here is the full boot messages:
>
>
[...]
>
>Unexpected interruption: Code=13 regs=100683c0 (Addr=00000000)
>
> YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI
>PSW: 00000000000001001111111100001111 Not tainted
>r00-03 00000000 ffffffff 10215854 1046d0c4
>r04-07 00000000 10068288 00000013 10388810
>r08-11 00000027 00000000 37e45480 10458884
>r12-15 3b9aca00 10389810 10458810 f0400004
>r16-19 f00008c4 f000017c f0000174 00009600
>r20-23 00000000 41000000 00000cb0 00000000
>r24-27 00000000 00000000 00000000 10372010
>r28-31 00000000 068e7780 100683c0 10210928
>sr0-3 00000000 00000000 00000000 00000000
>sr4-7 00000000 00000000 00000000 00000000
>
>IASQ: 00000000 00000000 IAOQ: 101e930c 101e9310
> IIR: b3202000 ISR: 10240000 IOR: 1a06836c
> CPU: 0 CR30: 10068000 CR31: 103cb000
> ORIG_R28: 10459010
> IAOQ[0]: $$divU+0xc/0x210
> IAOQ[1]: $$divU+0x10/0x210
> RP(r2): serial8250_get_divisor+0x44/0x50
>
>
>
Hi Carlos and all,
Regarding a bit more about this crash dump, I figure out that your patch
<http://lists.parisc-linux.org/pipermail/parisc-linux/2002-September/017565.html>
was not yet 'aligned' in 2.6.
So may I suggest you this first draft:
--- linux-2.6.0-test6-pa6.orig/arch/parisc/kernel/traps.c
2003-10-05 16:03:42.000000000 +0200
+++ linux-2.6.0-test6-pa6.test/arch/parisc/kernel/traps.c
2003-10-05 16:05:24.000000000 +0200
@@ -44,7 +44,7 @@
#define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
/* dumped to the console via printk) */
-int printbinary(char *buf, unsigned long x, int nbits)
+static int printbinary(char *buf, unsigned long x, int nbits)
{
unsigned long mask = 1UL << (nbits - 1);
while (mask != 0) {
@@ -408,7 +408,7 @@
/*
- * This routine handles page faults. It determines the address,
+ * This routine handles various exception codes. It determines the
address,
* and the problem, and then passes it off to one of the appropriate
* routines.
*/
@@ -429,8 +429,18 @@
if (!console_drivers)
pdc_console_restart();
- if (code == 1)
- transfer_pim_to_trap_frame(regs);
+
+ /* Not all switch paths will gutter the processor... */
+ switch(code){
+
+ case 1:
+ transfer_pim_to_trap_frame(regs);
+ break;
+
+ default:
+ /* Fall through */
+ break;
+ }
show_stack(NULL, (unsigned long *)regs->gr[30]);
@@ -446,34 +456,28 @@
* system will shut down immediately right here. */
pdc_soft_power_button(0);
+ /* Gutter the processor... */
for(;;)
;
}
+
void handle_interruption(int code, struct pt_regs *regs)
{
unsigned long fault_address = 0;
unsigned long fault_space = 0;
struct siginfo si;
- if (code == 1)
- pdc_console_restart(); /* switch back to pdc if HPMC */
- else
- local_irq_enable();
-
-#if 0
- printk(KERN_CRIT "Interruption # %d\n", code);
-#endif
-
switch(code) {
case 1:
/* High-priority machine check (HPMC) */
-
+ pdc_console_restart(); /* switch back to pdc if HPMC */
+
/* set up a new led state on systems shipped with a LED
State panel */
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);
-
- parisc_terminate("High Priority Machine Check (HPMC)",
+
+ parisc_terminate("High Priority Machine Check (HPMC)",
regs, code, 0);
/* NOT REACHED */
@@ -492,8 +496,9 @@
case 5:
/* Low-priority machine check */
+
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);
-
+
flush_all_caches();
cpu_lpmc(5, regs);
return;
@@ -542,6 +547,7 @@
die_if_kernel("Privileged register usage", regs, code);
si.si_code = ILL_PRVREG;
+ /* Fall thru */
give_sigill:
si.si_signo = SIGILL;
si.si_errno = 0;
@@ -556,6 +562,17 @@
si.si_addr = (void *) regs->iaoq[0];
force_sig_info(SIGFPE, &si, current);
return;
+
+ case 13:
+ /* Conditional Trap
+ The condition succees in an instruction which traps
on condition */
+ si.si_signo = SIGFPE;
+ /* Set to zero, and let the userspace app figure it out from
+ the insn pointed to by si_addr */
+ si.si_code = 0;
+ si.si_addr = (void *) regs->iaoq[0];
+ force_sig_info(SIGFPE, &si, current);
+ return;
case 14:
/* Assist Exception Trap, i.e. floating point exception. */
@@ -563,13 +580,22 @@
handle_fpe(regs);
return;
+ case 15:
+ /* Data TLB miss fault/Data page fault */
+ /* Fall thru */
+ case 16:
+ /* Non-access instruction TLB miss fault */
+ /* The instruction TLB entry needed for the target
address of the FIC
+ is absent, and hardware can't find it, so we get to
cleanup */
+ /* Fall thru */
case 17:
/* Non-access data TLB miss fault/Non-access data page
fault */
/* TODO: Still need to add slow path emulation code here */
- pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
-
+ /* TODO: Understand what is meant by the TODO listed
+ above this one. (Carlos) */
fault_address = regs->ior;
- parisc_terminate("Non access data tlb
fault!",regs,code,fault_address);
+ fault_space = regs->isr;
+ break;
case 18:
/* PCXS only -- later cpu's split this into types 26,27
& 28 */
@@ -579,9 +605,8 @@
return;
}
/* Fall Through */
-
- case 15: /* Data TLB miss fault/Data page fault */
- case 26: /* PCXL: Data memory access rights trap */
+ case 26:
+ /* PCXL: Data memory access rights trap */
fault_address = regs->ior;
fault_space = regs->isr;
break;
@@ -637,7 +662,6 @@
up_read(¤t->mm->mmap_sem);
}
/* Fall Through */
-
case 27:
/* Data memory protection ID trap */
die_if_kernel("Protection id trap", regs, code);
@@ -671,8 +695,9 @@
force_sig_info(SIGBUS, &si, current);
return;
}
- pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
+ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
+
parisc_terminate("Unexpected interruption", regs, code, 0);
/* NOT REACHED */
}
@@ -702,18 +727,19 @@
* The kernel should never fault on its own address space.
*/
- if (fault_space == 0)
- {
+ if (fault_space == 0) {
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
parisc_terminate("Kernel Fault", regs, code, fault_address);
-
+ /** NOT REACHED **/
}
}
+ local_irq_enable();
do_page_fault(regs, code, fault_address);
}
+
int __init check_ivt(void *iva)
{
int i;
hmm I am not quiet sure about first hunck (static or not for printbinary?).
I test it successfully on my c110 but if you have some opportunity to
double check and may be also ci, that would be nice.
Thanks in advance,
Joel
PS: I do not yet test on my b2k :( so I don't know yet if it help the
above pb?
PS2: Max may be have this opportunity on your c3k? (thanks)
--------------030403020700060302040201
Content-Type: text/plain;
name="Traps-2.4-Align"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Traps-2.4-Align"
--- linux-2.6.0-test6-pa6.orig/arch/parisc/kernel/traps.c 2003-10-05 16:03:42.000000000 +0200
+++ linux-2.6.0-test6-pa6.test/arch/parisc/kernel/traps.c 2003-10-05 16:05:24.000000000 +0200
@@ -44,7 +44,7 @@
#define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
/* dumped to the console via printk) */
-int printbinary(char *buf, unsigned long x, int nbits)
+static int printbinary(char *buf, unsigned long x, int nbits)
{
unsigned long mask = 1UL << (nbits - 1);
while (mask != 0) {
@@ -408,7 +408,7 @@
/*
- * This routine handles page faults. It determines the address,
+ * This routine handles various exception codes. It determines the address,
* and the problem, and then passes it off to one of the appropriate
* routines.
*/
@@ -429,8 +429,18 @@
if (!console_drivers)
pdc_console_restart();
- if (code == 1)
- transfer_pim_to_trap_frame(regs);
+
+ /* Not all switch paths will gutter the processor... */
+ switch(code){
+
+ case 1:
+ transfer_pim_to_trap_frame(regs);
+ break;
+
+ default:
+ /* Fall through */
+ break;
+ }
show_stack(NULL, (unsigned long *)regs->gr[30]);
@@ -446,34 +456,28 @@
* system will shut down immediately right here. */
pdc_soft_power_button(0);
+ /* Gutter the processor... */
for(;;)
;
}
+
void handle_interruption(int code, struct pt_regs *regs)
{
unsigned long fault_address = 0;
unsigned long fault_space = 0;
struct siginfo si;
- if (code == 1)
- pdc_console_restart(); /* switch back to pdc if HPMC */
- else
- local_irq_enable();
-
-#if 0
- printk(KERN_CRIT "Interruption # %d\n", code);
-#endif
-
switch(code) {
case 1:
/* High-priority machine check (HPMC) */
-
+ pdc_console_restart(); /* switch back to pdc if HPMC */
+
/* set up a new led state on systems shipped with a LED State panel */
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);
-
- parisc_terminate("High Priority Machine Check (HPMC)",
+
+ parisc_terminate("High Priority Machine Check (HPMC)",
regs, code, 0);
/* NOT REACHED */
@@ -492,8 +496,9 @@
case 5:
/* Low-priority machine check */
+
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);
-
+
flush_all_caches();
cpu_lpmc(5, regs);
return;
@@ -542,6 +547,7 @@
die_if_kernel("Privileged register usage", regs, code);
si.si_code = ILL_PRVREG;
+ /* Fall thru */
give_sigill:
si.si_signo = SIGILL;
si.si_errno = 0;
@@ -556,6 +562,17 @@
si.si_addr = (void *) regs->iaoq[0];
force_sig_info(SIGFPE, &si, current);
return;
+
+ case 13:
+ /* Conditional Trap
+ The condition succees in an instruction which traps on condition */
+ si.si_signo = SIGFPE;
+ /* Set to zero, and let the userspace app figure it out from
+ the insn pointed to by si_addr */
+ si.si_code = 0;
+ si.si_addr = (void *) regs->iaoq[0];
+ force_sig_info(SIGFPE, &si, current);
+ return;
case 14:
/* Assist Exception Trap, i.e. floating point exception. */
@@ -563,13 +580,22 @@
handle_fpe(regs);
return;
+ case 15:
+ /* Data TLB miss fault/Data page fault */
+ /* Fall thru */
+ case 16:
+ /* Non-access instruction TLB miss fault */
+ /* The instruction TLB entry needed for the target address of the FIC
+ is absent, and hardware can't find it, so we get to cleanup */
+ /* Fall thru */
case 17:
/* Non-access data TLB miss fault/Non-access data page fault */
/* TODO: Still need to add slow path emulation code here */
- pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
-
+ /* TODO: Understand what is meant by the TODO listed
+ above this one. (Carlos) */
fault_address = regs->ior;
- parisc_terminate("Non access data tlb fault!",regs,code,fault_address);
+ fault_space = regs->isr;
+ break;
case 18:
/* PCXS only -- later cpu's split this into types 26,27 & 28 */
@@ -579,9 +605,8 @@
return;
}
/* Fall Through */
-
- case 15: /* Data TLB miss fault/Data page fault */
- case 26: /* PCXL: Data memory access rights trap */
+ case 26:
+ /* PCXL: Data memory access rights trap */
fault_address = regs->ior;
fault_space = regs->isr;
break;
@@ -637,7 +662,6 @@
up_read(¤t->mm->mmap_sem);
}
/* Fall Through */
-
case 27:
/* Data memory protection ID trap */
die_if_kernel("Protection id trap", regs, code);
@@ -671,8 +695,9 @@
force_sig_info(SIGBUS, &si, current);
return;
}
- pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
+ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
+
parisc_terminate("Unexpected interruption", regs, code, 0);
/* NOT REACHED */
}
@@ -702,18 +727,19 @@
* The kernel should never fault on its own address space.
*/
- if (fault_space == 0)
- {
+ if (fault_space == 0) {
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
parisc_terminate("Kernel Fault", regs, code, fault_address);
-
+ /** NOT REACHED **/
}
}
+ local_irq_enable();
do_page_fault(regs, code, fault_address);
}
+
int __init check_ivt(void *iva)
{
int i;
--------------030403020700060302040201--