From: Michael Neuling <hidden> Date: 2007-12-12 05:45:12
This adds hooks into the default_machine_crash_shutdown so drivers can
register a function to be run in the first kernel before we hand off
to the second kernel. This should only be used in exceptional
circumstances, like where the device can't be reset in the second
kernel alone (as is the case with eHEA). To emphasize this, the
number of handles allowed to be registered is currently #def to 1.
This uses the setjmp/longjmp code to call out to the registered hooks,
so any bogus exceptions we encounter will hopefully be recoverable.
I've tested with bogus data and instruction exceptions.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/crash.c | 90 +++++++++++++++++++++++++++++++++++++++++---
include/asm-powerpc/kexec.h | 3 +
2 files changed, 88 insertions(+), 5 deletions(-)
Index: linux-2.6-ozlabs/arch/powerpc/kernel/crash.c
===================================================================
@@ -285,9 +292,69 @@ static inline void crash_kexec_stop_spus } #endif /* CONFIG_SPU_BASE */+/* + * Register a function to be called on shutdown. Only use this if you+ * can't reset your device in the second kernel.+ */+int crash_shutdown_register(crash_shutdown_t handler)+{+ unsigned int i;++ spin_lock(&crash_handles_lock);+ for(i = 0 ; i <= CRASH_SHUTDOWN_HANDLES_NUM; i++)
Missing space after for. There's a handful more of these through the
patch.
quoted hunk
+ if (!crash_shutdown_handles[i])
+ break;
+
+ if (i == CRASH_SHUTDOWN_HANDLES_NUM){
+ printk(KERN_ERR "Crash shutdown handles full, "
+ "not registered.\n");
+ spin_unlock(&crash_handles_lock);
+ return 1;
+ }
+
+ /* Insert handle at end */
+ crash_shutdown_handles[i] = handler;
+ spin_unlock(&crash_handles_lock);
+ return 0;
+}
+EXPORT_SYMBOL(crash_shutdown_register);
+
+int crash_shutdown_unregister(crash_shutdown_t handler)
+{
+ unsigned int i;
+
+ spin_lock(&crash_handles_lock);
+ for(i = 0 ; i <= CRASH_SHUTDOWN_HANDLES_NUM; i++)
+ if (crash_shutdown_handles[i] == handler)
+ break;
+
+ if (i == CRASH_SHUTDOWN_HANDLES_NUM){
+ printk(KERN_ERR "Crash shutdown handle not found\n");
+ spin_unlock(&crash_handles_lock);
+ return 1;
+ }
+
+ /* Shift handles down */
+ while(crash_shutdown_handles[i]) {
+ crash_shutdown_handles[i] = crash_shutdown_handles[i+1];
+ i++;
+ }
+ spin_unlock(&crash_handles_lock);
+ return 0;
+}
+EXPORT_SYMBOL(crash_shutdown_unregister);
+
+static long crash_shutdown_buf[SETJMP_BUF_LEN];
+
+static int handle_fault(struct pt_regs *regs)
+{
+ longjmp(crash_shutdown_buf, 1);
+ return 0;
+}
+
void default_machine_crash_shutdown(struct pt_regs *regs)
{
- unsigned int irq;
+ unsigned int i;
/*
* This function is only called after the system
This looks a bit random. Why the handcoded barriers, and why the delay?
At least comment why the delay is needed (and why just 200 is
sufficient). I don't see a need for the barriers at all here?
From: Michael Ellerman <hidden> Date: 2007-12-12 23:07:19
On Wed, 2007-12-12 at 16:45 +1100, Michael Neuling wrote:
quoted hunk
This adds hooks into the default_machine_crash_shutdown so drivers can
register a function to be run in the first kernel before we hand off
to the second kernel. This should only be used in exceptional
circumstances, like where the device can't be reset in the second
kernel alone (as is the case with eHEA). To emphasize this, the
number of handles allowed to be registered is currently #def to 1.
This uses the setjmp/longjmp code to call out to the registered hooks,
so any bogus exceptions we encounter will hopefully be recoverable.
I've tested with bogus data and instruction exceptions.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/crash.c | 90 +++++++++++++++++++++++++++++++++++++++++---
include/asm-powerpc/kexec.h | 3 +
2 files changed, 88 insertions(+), 5 deletions(-)
Index: linux-2.6-ozlabs/arch/powerpc/kernel/crash.c
===================================================================
@@ -285,9 +292,69 @@ static inline void crash_kexec_stop_spus } #endif /* CONFIG_SPU_BASE */+/* + * Register a function to be called on shutdown. Only use this if you+ * can't reset your device in the second kernel.+ */+int crash_shutdown_register(crash_shutdown_t handler)+{+ unsigned int i, rc;++ spin_lock(&crash_handles_lock);
+ for(i = 0 ; i <= CRASH_SHUTDOWN_HANDLES_NUM; i++) {
+ if (!crash_shutdown_handles[i]) {
+ /* Insert handle at end */
+ crash_shutdown_handles[i] = handler;
+ rc = 0;
+ break;
+ }
+ }
+ if (i == CRASH_SHUTDOWN_HANDLES_NUM){
+ printk(KERN_ERR "Crash shutdown handles full, "
+ "not registered.\n");
+ rc = 1;
+ }
+
+ spin_unlock(&crash_handles_lock);
+
+static int handle_fault(struct pt_regs *regs)
+{
+ longjmp(crash_shutdown_buf, 1);
+ return 0;
+}
+
void default_machine_crash_shutdown(struct pt_regs *regs)
{
- unsigned int irq;
+ unsigned int i;
/*
* This function is only called after the system
You should probably reset __debugger_fault_handler, just to be safe.
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
From: Michael Neuling <hidden> Date: 2007-12-13 00:04:02
In message <1197500839.7695.19.camel@concordia> you wrote:
--=-Kza0KCx0MG8nsjfq7kOz
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable
On Wed, 2007-12-12 at 16:45 +1100, Michael Neuling wrote:
quoted
This adds hooks into the default_machine_crash_shutdown so drivers can
register a function to be run in the first kernel before we hand off
to the second kernel. This should only be used in exceptional
circumstances, like where the device can't be reset in the second
kernel alone (as is the case with eHEA). To emphasize this, the
number of handles allowed to be registered is currently #def to 1.
=20
This uses the setjmp/longjmp code to call out to the registered hooks,
so any bogus exceptions we encounter will hopefully be recoverable. =20
=20
I've tested with bogus data and instruction exceptions.
=20
Signed-off-by: Michael Neuling <redacted>
---
=20
arch/powerpc/kernel/crash.c | 90 +++++++++++++++++++++++++++++++++++++=
=20
+/*=20
+ * Register a function to be called on shutdown. Only use this if you
+ * can't reset your device in the second kernel.
+ */
+int crash_shutdown_register(crash_shutdown_t handler)
+{
+ unsigned int i, rc;
+
+ spin_lock(&crash_handles_lock);
quoted
+ for(i =3D 0 ; i <=3D CRASH_SHUTDOWN_HANDLES_NUM; i++) {
+ if (!crash_shutdown_handles[i]) {
+ /* Insert handle at end */
+ crash_shutdown_handles[i] =3D handler;
+ rc =3D 0;
+ break;
+ }
+ }
=20
+ if (i =3D=3D CRASH_SHUTDOWN_HANDLES_NUM){
+ printk(KERN_ERR "Crash shutdown handles full, "
+ "not registered.\n");
+ rc =3D 1;
+ }
+
+ spin_unlock(&crash_handles_lock);
+
+static int handle_fault(struct pt_regs *regs)
+{
+ longjmp(crash_shutdown_buf, 1);
+ return 0;
+}
+
void default_machine_crash_shutdown(struct pt_regs *regs)
{
- unsigned int irq;
+ unsigned int i;
=20
/*
* This function is only called after the system
This looks a bit random. Why the handcoded barriers, and why the delay?
I don't see a need for the barriers at all here?
I was following the bouncing ball here from the xmon code. We don't
want the hardware executing any of potentially dangerous hooks before
we've setup the setjmp save buffer. Similar, any code past the
dangerous hooks shouldn't be executed before we take a machine check.
It's definitely not a fast path so.... :-)
At least comment why the delay is needed (and why just 200 is
sufficient).
xmon.c says:
/* wait a little while to see if we get a machine check */
I'll update the "200" with a #define SETJMP_MACHINE_CHECK_DELAY and push
the same change into the xmon code. This delay in the machine check is
apparently required on 601 machines.
All you other comments I agree with.
Mikey
From: Michael Neuling <hidden> Date: 2007-12-13 03:16:17
The following patches add crashdump shutdown hooks for POWERPC.
Signed-off-by: Michael Neuling <redacted>
---
This is an updated series following comments from the first post.
Adds some documentation, better code flow, fixes 32 bit compiles and
other updates based on feedback
Again these are based on paulus' for 2.6.25 tree.
From: Michael Neuling <hidden> Date: 2007-12-13 03:16:18
This makes the setjmp/longjmp code used by xmon, generically available
to other code. It also removes the requirement for debugger hooks to
be only called on 0x300 (data storage) exception and adds some
documentation.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/misc.S | 128 ++++++++++++++++++++++++++++++++++++++++
arch/powerpc/mm/fault.c | 6 -
arch/powerpc/xmon/Makefile | 2
arch/powerpc/xmon/setjmp.S | 135 -------------------------------------------
arch/powerpc/xmon/xmon.c | 38 ++++--------
include/asm-powerpc/setjmp.h | 19 ++++++
6 files changed, 164 insertions(+), 164 deletions(-)
Index: clone3/arch/powerpc/kernel/misc.S
===================================================================
@@ -51,3 +55,127 @@ _GLOBAL(kernel_execve)bnslrnegr3,r3blr++_GLOBAL(setjmp)+mflrr0+PPC_STLr0,0(r3)+PPC_STLr1,SZL(r3)+PPC_STLr2,2*SZL(r3)+mfcrr0+PPC_STLr0,3*SZL(r3)+PPC_STLr13,4*SZL(r3)+PPC_STLr14,5*SZL(r3)+PPC_STLr15,6*SZL(r3)+PPC_STLr16,7*SZL(r3)+PPC_STLr17,8*SZL(r3)+PPC_STLr18,9*SZL(r3)+PPC_STLr19,10*SZL(r3)+PPC_STLr20,11*SZL(r3)+PPC_STLr21,12*SZL(r3)+PPC_STLr22,13*SZL(r3)+PPC_STLr23,14*SZL(r3)+PPC_STLr24,15*SZL(r3)+PPC_STLr25,16*SZL(r3)+PPC_STLr26,17*SZL(r3)+PPC_STLr27,18*SZL(r3)+PPC_STLr28,19*SZL(r3)+PPC_STLr29,20*SZL(r3)+PPC_STLr30,21*SZL(r3)+PPC_STLr31,22*SZL(r3)+lir3,0+blr++_GLOBAL(longjmp)+PPC_LCMPIr4,0+bne1f+lir4,1+1:PPC_LLr13,4*SZL(r3)+PPC_LLr14,5*SZL(r3)+PPC_LLr15,6*SZL(r3)+PPC_LLr16,7*SZL(r3)+PPC_LLr17,8*SZL(r3)+PPC_LLr18,9*SZL(r3)+PPC_LLr19,10*SZL(r3)+PPC_LLr20,11*SZL(r3)+PPC_LLr21,12*SZL(r3)+PPC_LLr22,13*SZL(r3)+PPC_LLr23,14*SZL(r3)+PPC_LLr24,15*SZL(r3)+PPC_LLr25,16*SZL(r3)+PPC_LLr26,17*SZL(r3)+PPC_LLr27,18*SZL(r3)+PPC_LLr28,19*SZL(r3)+PPC_LLr29,20*SZL(r3)+PPC_LLr30,21*SZL(r3)+PPC_LLr31,22*SZL(r3)+PPC_LLr0,3*SZL(r3)+mtcrf0x38,r0+PPC_LLr0,0(r3)+PPC_LLr1,SZL(r3)+PPC_LLr2,2*SZL(r3)+mtlrr0+mrr3,r4+blr++#ifdef CONFIG_XMON+/*+*Grabtheregistervaluesastheyarenow.+*Thiswon't do a particularily good job because we really+*wantourcaller's caller'sregisters,andourcallerhas+*alreadyexecuteditsprologue.+*ToDo:Wecouldreachbackintothecaller's save area to do+*abetterjobofrepresentingthecaller's state (note that+*thatwillbedifferentfor32-bitand64-bit,becauseofthe+*differentABIs,though).+*/+_GLOBAL(xmon_save_regs)+PPC_STLr0,0*SZL(r3)+PPC_STLr2,2*SZL(r3)+PPC_STLr3,3*SZL(r3)+PPC_STLr4,4*SZL(r3)+PPC_STLr5,5*SZL(r3)+PPC_STLr6,6*SZL(r3)+PPC_STLr7,7*SZL(r3)+PPC_STLr8,8*SZL(r3)+PPC_STLr9,9*SZL(r3)+PPC_STLr10,10*SZL(r3)+PPC_STLr11,11*SZL(r3)+PPC_STLr12,12*SZL(r3)+PPC_STLr13,13*SZL(r3)+PPC_STLr14,14*SZL(r3)+PPC_STLr15,15*SZL(r3)+PPC_STLr16,16*SZL(r3)+PPC_STLr17,17*SZL(r3)+PPC_STLr18,18*SZL(r3)+PPC_STLr19,19*SZL(r3)+PPC_STLr20,20*SZL(r3)+PPC_STLr21,21*SZL(r3)+PPC_STLr22,22*SZL(r3)+PPC_STLr23,23*SZL(r3)+PPC_STLr24,24*SZL(r3)+PPC_STLr25,25*SZL(r3)+PPC_STLr26,26*SZL(r3)+PPC_STLr27,27*SZL(r3)+PPC_STLr28,28*SZL(r3)+PPC_STLr29,29*SZL(r3)+PPC_STLr30,30*SZL(r3)+PPC_STLr31,31*SZL(r3)+/*gouponestackframeforSP*/+PPC_LLr4,0(r1)+PPC_STLr4,1*SZL(r3)+/*getcaller's LR */+PPC_LLr0,LRSAVE(r4)+PPC_STLr0,_NIP-STACK_FRAME_OVERHEAD(r3)+PPC_STLr0,_LINK-STACK_FRAME_OVERHEAD(r3)+mfmsrr0+PPC_STLr0,_MSR-STACK_FRAME_OVERHEAD(r3)+mfctrr0+PPC_STLr0,_CTR-STACK_FRAME_OVERHEAD(r3)+mfxerr0+PPC_STLr0,_XER-STACK_FRAME_OVERHEAD(r3)+mfcrr0+PPC_STLr0,_CCR-STACK_FRAME_OVERHEAD(r3)+lir0,0+PPC_STLr0,_TRAP-STACK_FRAME_OVERHEAD(r3)+blr+#endif
@@ -167,10 +167,8 @@ int __kprobes do_page_fault(struct pt_reif(notify_page_fault(regs))return0;-if(trap==0x300){-if(debugger_fault_handler(regs))-return0;-}+if(unlikely(debugger_fault_handler(regs)))+return0;/* On a kernel SLB miss we can only check for a valid exception entry */if(!user_mode(regs)&&(address>=TASK_SIZE))
@@ -1497,8 +1493,7 @@ void cacheflush(void)cinval((void*)adrs);}sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);}catch_memory_errors=0;}
@@ -1533,8 +1528,7 @@ read_spr(int n)ret=code();sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);n=size;}
@@ -1569,8 +1563,7 @@ write_spr(int n, unsigned long val)code(val);sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);n=size;}}
@@ -1676,8 +1669,7 @@ mread(unsigned long adrs, void *buf, int}}sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);n=size;}catch_memory_errors=0;
@@ -1713,8 +1705,7 @@ mwrite(unsigned long adrs, void *buf, in}}sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);n=size;}else{printf("*** Error writing address %x\n",adrs+n);
@@ -2521,8 +2512,7 @@ static void xmon_print_symbol(unsigned lname=kallsyms_lookup(address,&size,&offset,&modname,tmpstr);sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);}catch_memory_errors=0;
From: Michael Neuling <hidden> Date: 2007-12-13 03:16:18
This adds hooks into the default_machine_crash_shutdown so drivers can
register a function to be run in the first kernel before we hand off
to the second kernel. This should only be used in exceptional
circumstances, like where the device can't be reset in the second
kernel alone (as is the case with eHEA). To emphasize this, the
number of handles allowed to be registered is currently #def to 1.
This uses the setjmp/longjmp code to call out to the registered hooks,
so any bogus exceptions we encounter will hopefully be recoverable.
Tested with bogus data and instruction exceptions.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/crash.c | 102 +++++++++++++++++++++++++++++++++++++++++---
include/asm-powerpc/kexec.h | 3 +
2 files changed, 100 insertions(+), 5 deletions(-)
Index: clone3/arch/powerpc/kernel/crash.c
===================================================================
@@ -285,9 +292,72 @@ static inline void crash_kexec_stop_spus } #endif /* CONFIG_SPU_BASE */+/*+ * Register a function to be called on shutdown. Only use this if you+ * can't reset your device in the second kernel.+ */+int crash_shutdown_register(crash_shutdown_t handler)+{+ unsigned int i, rc;++ spin_lock(&crash_handers_lock);+ for (i = 0 ; i < CRASH_HANDLER_MAX; i++)+ if (!crash_shutdown_handles[i]) {+ /* Insert handle at first empty entry */+ crash_shutdown_handles[i] = handler;+ rc = 0;+ break;+ }++ if (i == CRASH_HANDLER_MAX) {+ printk(KERN_ERR "Crash shutdown handles full, "+ "not registered.\n");+ rc = 1;+ }++ spin_unlock(&crash_handers_lock);+ return rc;+}+EXPORT_SYMBOL(crash_shutdown_register);++int crash_shutdown_unregister(crash_shutdown_t handler)+{+ unsigned int i, rc;++ spin_lock(&crash_handers_lock);+ for (i = 0 ; i < CRASH_HANDLER_MAX; i++)+ if (crash_shutdown_handles[i] == handler)+ break;++ if (i == CRASH_HANDLER_MAX) {+ printk(KERN_ERR "Crash shutdown handle not found\n");+ rc = 1;+ } else {+ /* Shift handles down */+ for (; crash_shutdown_handles[i]; i++)+ crash_shutdown_handles[i] =+ crash_shutdown_handles[i+1];+ rc = 0;+ }++ spin_unlock(&crash_handers_lock);+ return rc;+}+EXPORT_SYMBOL(crash_shutdown_unregister);++static unsigned long crash_shutdown_buf[SETJMP_BUF_LEN];++static int handle_fault(struct pt_regs *regs)+{+ longjmp(crash_shutdown_buf, 1);+ return 0;+}+ void default_machine_crash_shutdown(struct pt_regs *regs) {- unsigned int irq;+ unsigned int i;+ int (*old_handler)(struct pt_regs *regs);+ /* * This function is only called after the system
@@ -301,15 +371,37 @@ void default_machine_crash_shutdown(stru */ hard_irq_disable();- for_each_irq(irq) {- struct irq_desc *desc = irq_desc + irq;+ for_each_irq(i) {+ struct irq_desc *desc = irq_desc + i; if (desc->status & IRQ_INPROGRESS)- desc->chip->eoi(irq);+ desc->chip->eoi(i); if (!(desc->status & IRQ_DISABLED))- desc->chip->disable(irq);+ desc->chip->disable(i);+ }++ /*+ * Call registered shutdown routines savely. Swap out+ * __debugger_fault_handler, and replace on exit.+ */+ old_handler = __debugger_fault_handler;+ __debugger_fault_handler = handle_fault;+ for (i = 0; crash_shutdown_handles[i]; i++) {+ if (setjmp(crash_shutdown_buf) == 0) {+ /*+ * Insert syncs and delay to ensure+ * instructions in the dangerous region don't+ * leak away from this protected region.+ */+ asm volatile("sync; isync");+ /* dangerous region */+ crash_shutdown_handles[i]();+ asm volatile("sync; isync");+ __delay(SETJMP_MACHINE_CHECK_DELAY);
Where is this defined?
quoted hunk
+ }
}
+ __debugger_fault_handler = old_handler;
/*
* Make a note of crashing cpu. Will be used in machine_kexec
Index: clone3/include/asm-powerpc/kexec.h
===================================================================
From: Michael Neuling <hidden> Date: 2007-12-13 09:59:17
The following patches add crashdump shutdown hooks for POWERPC.
Signed-off-by: Michael Neuling <redacted>
---
Fixes stupid variable name noticed by Olof.
From: Michael Neuling <hidden> Date: 2007-12-13 09:59:17
This makes the setjmp/longjmp code used by xmon, generically available
to other code. It also removes the requirement for debugger hooks to
be only called on 0x300 (data storage) exception and adds some
documentation.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/misc.S | 128 ++++++++++++++++++++++++++++++++++++++++
arch/powerpc/mm/fault.c | 6 -
arch/powerpc/xmon/Makefile | 2
arch/powerpc/xmon/setjmp.S | 135 -------------------------------------------
arch/powerpc/xmon/xmon.c | 38 ++++--------
include/asm-powerpc/setjmp.h | 19 ++++++
6 files changed, 164 insertions(+), 164 deletions(-)
Index: clone3/arch/powerpc/kernel/misc.S
===================================================================
@@ -51,3 +55,127 @@ _GLOBAL(kernel_execve)bnslrnegr3,r3blr++_GLOBAL(setjmp)+mflrr0+PPC_STLr0,0(r3)+PPC_STLr1,SZL(r3)+PPC_STLr2,2*SZL(r3)+mfcrr0+PPC_STLr0,3*SZL(r3)+PPC_STLr13,4*SZL(r3)+PPC_STLr14,5*SZL(r3)+PPC_STLr15,6*SZL(r3)+PPC_STLr16,7*SZL(r3)+PPC_STLr17,8*SZL(r3)+PPC_STLr18,9*SZL(r3)+PPC_STLr19,10*SZL(r3)+PPC_STLr20,11*SZL(r3)+PPC_STLr21,12*SZL(r3)+PPC_STLr22,13*SZL(r3)+PPC_STLr23,14*SZL(r3)+PPC_STLr24,15*SZL(r3)+PPC_STLr25,16*SZL(r3)+PPC_STLr26,17*SZL(r3)+PPC_STLr27,18*SZL(r3)+PPC_STLr28,19*SZL(r3)+PPC_STLr29,20*SZL(r3)+PPC_STLr30,21*SZL(r3)+PPC_STLr31,22*SZL(r3)+lir3,0+blr++_GLOBAL(longjmp)+PPC_LCMPIr4,0+bne1f+lir4,1+1:PPC_LLr13,4*SZL(r3)+PPC_LLr14,5*SZL(r3)+PPC_LLr15,6*SZL(r3)+PPC_LLr16,7*SZL(r3)+PPC_LLr17,8*SZL(r3)+PPC_LLr18,9*SZL(r3)+PPC_LLr19,10*SZL(r3)+PPC_LLr20,11*SZL(r3)+PPC_LLr21,12*SZL(r3)+PPC_LLr22,13*SZL(r3)+PPC_LLr23,14*SZL(r3)+PPC_LLr24,15*SZL(r3)+PPC_LLr25,16*SZL(r3)+PPC_LLr26,17*SZL(r3)+PPC_LLr27,18*SZL(r3)+PPC_LLr28,19*SZL(r3)+PPC_LLr29,20*SZL(r3)+PPC_LLr30,21*SZL(r3)+PPC_LLr31,22*SZL(r3)+PPC_LLr0,3*SZL(r3)+mtcrf0x38,r0+PPC_LLr0,0(r3)+PPC_LLr1,SZL(r3)+PPC_LLr2,2*SZL(r3)+mtlrr0+mrr3,r4+blr++#ifdef CONFIG_XMON+/*+*Grabtheregistervaluesastheyarenow.+*Thiswon't do a particularily good job because we really+*wantourcaller's caller'sregisters,andourcallerhas+*alreadyexecuteditsprologue.+*ToDo:Wecouldreachbackintothecaller's save area to do+*abetterjobofrepresentingthecaller's state (note that+*thatwillbedifferentfor32-bitand64-bit,becauseofthe+*differentABIs,though).+*/+_GLOBAL(xmon_save_regs)+PPC_STLr0,0*SZL(r3)+PPC_STLr2,2*SZL(r3)+PPC_STLr3,3*SZL(r3)+PPC_STLr4,4*SZL(r3)+PPC_STLr5,5*SZL(r3)+PPC_STLr6,6*SZL(r3)+PPC_STLr7,7*SZL(r3)+PPC_STLr8,8*SZL(r3)+PPC_STLr9,9*SZL(r3)+PPC_STLr10,10*SZL(r3)+PPC_STLr11,11*SZL(r3)+PPC_STLr12,12*SZL(r3)+PPC_STLr13,13*SZL(r3)+PPC_STLr14,14*SZL(r3)+PPC_STLr15,15*SZL(r3)+PPC_STLr16,16*SZL(r3)+PPC_STLr17,17*SZL(r3)+PPC_STLr18,18*SZL(r3)+PPC_STLr19,19*SZL(r3)+PPC_STLr20,20*SZL(r3)+PPC_STLr21,21*SZL(r3)+PPC_STLr22,22*SZL(r3)+PPC_STLr23,23*SZL(r3)+PPC_STLr24,24*SZL(r3)+PPC_STLr25,25*SZL(r3)+PPC_STLr26,26*SZL(r3)+PPC_STLr27,27*SZL(r3)+PPC_STLr28,28*SZL(r3)+PPC_STLr29,29*SZL(r3)+PPC_STLr30,30*SZL(r3)+PPC_STLr31,31*SZL(r3)+/*gouponestackframeforSP*/+PPC_LLr4,0(r1)+PPC_STLr4,1*SZL(r3)+/*getcaller's LR */+PPC_LLr0,LRSAVE(r4)+PPC_STLr0,_NIP-STACK_FRAME_OVERHEAD(r3)+PPC_STLr0,_LINK-STACK_FRAME_OVERHEAD(r3)+mfmsrr0+PPC_STLr0,_MSR-STACK_FRAME_OVERHEAD(r3)+mfctrr0+PPC_STLr0,_CTR-STACK_FRAME_OVERHEAD(r3)+mfxerr0+PPC_STLr0,_XER-STACK_FRAME_OVERHEAD(r3)+mfcrr0+PPC_STLr0,_CCR-STACK_FRAME_OVERHEAD(r3)+lir0,0+PPC_STLr0,_TRAP-STACK_FRAME_OVERHEAD(r3)+blr+#endif
@@ -167,10 +167,8 @@ int __kprobes do_page_fault(struct pt_reif(notify_page_fault(regs))return0;-if(trap==0x300){-if(debugger_fault_handler(regs))-return0;-}+if(unlikely(debugger_fault_handler(regs)))+return0;/* On a kernel SLB miss we can only check for a valid exception entry */if(!user_mode(regs)&&(address>=TASK_SIZE))
@@ -1497,8 +1493,7 @@ void cacheflush(void)cinval((void*)adrs);}sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);}catch_memory_errors=0;}
@@ -1533,8 +1528,7 @@ read_spr(int n)ret=code();sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);n=size;}
@@ -1569,8 +1563,7 @@ write_spr(int n, unsigned long val)code(val);sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);n=size;}}
@@ -1676,8 +1669,7 @@ mread(unsigned long adrs, void *buf, int}}sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);n=size;}catch_memory_errors=0;
@@ -1713,8 +1705,7 @@ mwrite(unsigned long adrs, void *buf, in}}sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);n=size;}else{printf("*** Error writing address %x\n",adrs+n);
@@ -2521,8 +2512,7 @@ static void xmon_print_symbol(unsigned lname=kallsyms_lookup(address,&size,&offset,&modname,tmpstr);sync();-/* wait a little while to see if we get a machine check */-__delay(200);+__delay(SETJMP_MACHINE_CHECK_DELAY);}catch_memory_errors=0;
From: Michael Neuling <hidden> Date: 2007-12-13 09:59:17
This adds hooks into the default_machine_crash_shutdown so drivers can
register a function to be run in the first kernel before we hand off
to the second kernel. This should only be used in exceptional
circumstances, like where the device can't be reset in the second
kernel alone (as is the case with eHEA). To emphasize this, the
number of handles allowed to be registered is currently #def to 1.
This uses the setjmp/longjmp code to call out to the registered hooks,
so any bogus exceptions we encounter will hopefully be recoverable.
Tested with bogus data and instruction exceptions.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/crash.c | 102 +++++++++++++++++++++++++++++++++++++++++---
include/asm-powerpc/kexec.h | 3 +
2 files changed, 100 insertions(+), 5 deletions(-)
Index: clone3/arch/powerpc/kernel/crash.c
===================================================================
From: Michael Neuling <hidden> Date: 2008-01-17 04:45:42
This makes the setjmp/longjmp code used by xmon, generically available
to other code. It also removes the requirement for debugger hooks to
be only called on 0x300 (data storage) exception.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/misc.S | 65 +++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/mm/fault.c | 6 +--
arch/powerpc/xmon/setjmp.S | 61 ----------------------------------------
arch/powerpc/xmon/xmon.c | 6 ---
include/asm-powerpc/setjmp.h | 18 +++++++++++
5 files changed, 86 insertions(+), 70 deletions(-)
Index: linux-2.6-ozlabs/arch/powerpc/kernel/misc.S
===================================================================
@@ -167,10 +167,8 @@ int __kprobes do_page_fault(struct pt_reif(notify_page_fault(regs))return0;-if(trap==0x300){-if(debugger_fault_handler(regs))-return0;-}+if(unlikely(debugger_fault_handler(regs)))+return0;/* On a kernel SLB miss we can only check for a valid exception entry */if(!user_mode(regs)&&(address>=TASK_SIZE))
@@ -12,67 +12,6 @@#include <asm/ppc_asm.h>#include <asm/asm-offsets.h>-_GLOBAL(xmon_setjmp)-mflrr0-PPC_STLr0,0(r3)-PPC_STLr1,SZL(r3)-PPC_STLr2,2*SZL(r3)-mfcrr0-PPC_STLr0,3*SZL(r3)-PPC_STLr13,4*SZL(r3)-PPC_STLr14,5*SZL(r3)-PPC_STLr15,6*SZL(r3)-PPC_STLr16,7*SZL(r3)-PPC_STLr17,8*SZL(r3)-PPC_STLr18,9*SZL(r3)-PPC_STLr19,10*SZL(r3)-PPC_STLr20,11*SZL(r3)-PPC_STLr21,12*SZL(r3)-PPC_STLr22,13*SZL(r3)-PPC_STLr23,14*SZL(r3)-PPC_STLr24,15*SZL(r3)-PPC_STLr25,16*SZL(r3)-PPC_STLr26,17*SZL(r3)-PPC_STLr27,18*SZL(r3)-PPC_STLr28,19*SZL(r3)-PPC_STLr29,20*SZL(r3)-PPC_STLr30,21*SZL(r3)-PPC_STLr31,22*SZL(r3)-lir3,0-blr--_GLOBAL(xmon_longjmp)-PPC_LCMPIr4,0-bne1f-lir4,1-1:PPC_LLr13,4*SZL(r3)-PPC_LLr14,5*SZL(r3)-PPC_LLr15,6*SZL(r3)-PPC_LLr16,7*SZL(r3)-PPC_LLr17,8*SZL(r3)-PPC_LLr18,9*SZL(r3)-PPC_LLr19,10*SZL(r3)-PPC_LLr20,11*SZL(r3)-PPC_LLr21,12*SZL(r3)-PPC_LLr22,13*SZL(r3)-PPC_LLr23,14*SZL(r3)-PPC_LLr24,15*SZL(r3)-PPC_LLr25,16*SZL(r3)-PPC_LLr26,17*SZL(r3)-PPC_LLr27,18*SZL(r3)-PPC_LLr28,19*SZL(r3)-PPC_LLr29,20*SZL(r3)-PPC_LLr30,21*SZL(r3)-PPC_LLr31,22*SZL(r3)-PPC_LLr0,3*SZL(r3)-mtcrf0x38,r0-PPC_LLr0,0(r3)-PPC_LLr1,SZL(r3)-PPC_LLr2,2*SZL(r3)-mtlrr0-mrr3,r4-blr-/**Grabtheregistervaluesastheyarenow.*Thiswon't do a particularily good job because we really
From: Michael Neuling <hidden> Date: 2008-01-17 04:45:42
This adds hooks into the default_machine_crash_shutdown so drivers can
register a function to be run in the first kernel before we hand off
to the second kernel. This should only be used in exceptional
circumstances, like where the device can't be reset in the second
kernel alone (as is the case with eHEA). To emphasize this, the
number of handles allowed to be registered is currently #def to 1.
This uses the setjmp/longjmp code to call out to the registered hooks,
so any bogus exceptions we encounter will hopefully be recoverable.
Tested with bogus data and instruction exceptions.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/crash.c | 106 +++++++++++++++++++++++++++++++++++++++++---
include/asm-powerpc/kexec.h | 3 +
2 files changed, 104 insertions(+), 5 deletions(-)
Index: linux-2.6-ozlabs/arch/powerpc/kernel/crash.c
===================================================================
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+#ifndef _ASM_POWERPC_SETJMP_H
+#define _ASM_POWERPC_SETJMP_H
+
+#define JMP_BUF_LEN 23
+
+extern long setjmp(long *);
+extern void longjmp(long *, long);
+
+#endif /* _ASM_POWERPC_SETJMP_H */
From: Stephen Rothwell <hidden> Date: 2008-01-17 06:36:53
On Thu, 17 Jan 2008 16:36:49 +1100 Michael Neuling [off-list ref] wrote:
quoted
Should the above be inside #ifdef __KERNEL__?
Yep... _and_ it's 2008 now!
I think that if you don't list the file for exporting to user mode (in
the Kbuild file), then you shouldn't need the __KERNEL__ protectors.
But it is, indeed, 2008. :-)
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+#ifndef _ASM_POWERPC_SETJMP_H
+#define _ASM_POWERPC_SETJMP_H
+
+#define JMP_BUF_LEN 23
+
+extern long setjmp(long *);
+extern void longjmp(long *, long);
+
+#endif /* _ASM_POWERPC_SETJMP_H */
Should the above be inside #ifdef __KERNEL__?
Yep... _and_ it's 2008 now!
I'll update.
While you're off updating it, remove the (C). It's bogus and shouldn't
be there.
josh
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+#ifndef _ASM_POWERPC_SETJMP_H
+#define _ASM_POWERPC_SETJMP_H
+
+#define JMP_BUF_LEN 23
+
+extern long setjmp(long *);
+extern void longjmp(long *, long);
+
+#endif /* _ASM_POWERPC_SETJMP_H */
Should the above be inside #ifdef __KERNEL__?
Yep... _and_ it's 2008 now!
I'll update.
While you're off updating it, remove the (C). It's bogus and shouldn't
be there.
And it should say IBM corp too.
Oh and my car needs a wash when you're free ..
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
From: Michael Neuling <hidden> Date: 2008-01-17 22:16:07
The following patches add crashdump shutdown hooks for POWERPC.
Signed-off-by: Michael Neuling <redacted>
---
Updated some comments in the code, as noticed by sfr, Josh Boyer and a
dirty car owner.
From: Michael Neuling <hidden> Date: 2008-01-17 22:16:07
This makes the setjmp/longjmp code used by xmon, generically available
to other code. It also removes the requirement for debugger hooks to
be only called on 0x300 (data storage) exception.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/misc.S | 65 +++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/mm/fault.c | 6 +--
arch/powerpc/xmon/setjmp.S | 61 ----------------------------------------
arch/powerpc/xmon/xmon.c | 6 ---
include/asm-powerpc/setjmp.h | 18 +++++++++++
5 files changed, 86 insertions(+), 70 deletions(-)
Index: linux-2.6-ozlabs/arch/powerpc/kernel/misc.S
===================================================================
@@ -167,10 +167,8 @@ int __kprobes do_page_fault(struct pt_reif(notify_page_fault(regs))return0;-if(trap==0x300){-if(debugger_fault_handler(regs))-return0;-}+if(unlikely(debugger_fault_handler(regs)))+return0;/* On a kernel SLB miss we can only check for a valid exception entry */if(!user_mode(regs)&&(address>=TASK_SIZE))
@@ -12,67 +12,6 @@#include <asm/ppc_asm.h>#include <asm/asm-offsets.h>-_GLOBAL(xmon_setjmp)-mflrr0-PPC_STLr0,0(r3)-PPC_STLr1,SZL(r3)-PPC_STLr2,2*SZL(r3)-mfcrr0-PPC_STLr0,3*SZL(r3)-PPC_STLr13,4*SZL(r3)-PPC_STLr14,5*SZL(r3)-PPC_STLr15,6*SZL(r3)-PPC_STLr16,7*SZL(r3)-PPC_STLr17,8*SZL(r3)-PPC_STLr18,9*SZL(r3)-PPC_STLr19,10*SZL(r3)-PPC_STLr20,11*SZL(r3)-PPC_STLr21,12*SZL(r3)-PPC_STLr22,13*SZL(r3)-PPC_STLr23,14*SZL(r3)-PPC_STLr24,15*SZL(r3)-PPC_STLr25,16*SZL(r3)-PPC_STLr26,17*SZL(r3)-PPC_STLr27,18*SZL(r3)-PPC_STLr28,19*SZL(r3)-PPC_STLr29,20*SZL(r3)-PPC_STLr30,21*SZL(r3)-PPC_STLr31,22*SZL(r3)-lir3,0-blr--_GLOBAL(xmon_longjmp)-PPC_LCMPIr4,0-bne1f-lir4,1-1:PPC_LLr13,4*SZL(r3)-PPC_LLr14,5*SZL(r3)-PPC_LLr15,6*SZL(r3)-PPC_LLr16,7*SZL(r3)-PPC_LLr17,8*SZL(r3)-PPC_LLr18,9*SZL(r3)-PPC_LLr19,10*SZL(r3)-PPC_LLr20,11*SZL(r3)-PPC_LLr21,12*SZL(r3)-PPC_LLr22,13*SZL(r3)-PPC_LLr23,14*SZL(r3)-PPC_LLr24,15*SZL(r3)-PPC_LLr25,16*SZL(r3)-PPC_LLr26,17*SZL(r3)-PPC_LLr27,18*SZL(r3)-PPC_LLr28,19*SZL(r3)-PPC_LLr29,20*SZL(r3)-PPC_LLr30,21*SZL(r3)-PPC_LLr31,22*SZL(r3)-PPC_LLr0,3*SZL(r3)-mtcrf0x38,r0-PPC_LLr0,0(r3)-PPC_LLr1,SZL(r3)-PPC_LLr2,2*SZL(r3)-mtlrr0-mrr3,r4-blr-/**Grabtheregistervaluesastheyarenow.*Thiswon't do a particularily good job because we really
From: Michael Neuling <hidden> Date: 2008-01-18 04:50:30
The following patches add crashdump shutdown hooks for POWERPC.
Signed-off-by: Michael Neuling <redacted>
---
Sorry, last update didn't include both patches.
From: Michael Neuling <hidden> Date: 2008-01-18 04:50:30
This makes the setjmp/longjmp code used by xmon, generically available
to other code. It also removes the requirement for debugger hooks to
be only called on 0x300 (data storage) exception.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/misc.S | 65 +++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/mm/fault.c | 6 +--
arch/powerpc/xmon/setjmp.S | 61 ----------------------------------------
arch/powerpc/xmon/xmon.c | 6 ---
include/asm-powerpc/setjmp.h | 18 +++++++++++
5 files changed, 86 insertions(+), 70 deletions(-)
Index: linux-2.6-ozlabs/arch/powerpc/kernel/misc.S
===================================================================
@@ -167,10 +167,8 @@ int __kprobes do_page_fault(struct pt_reif(notify_page_fault(regs))return0;-if(trap==0x300){-if(debugger_fault_handler(regs))-return0;-}+if(unlikely(debugger_fault_handler(regs)))+return0;/* On a kernel SLB miss we can only check for a valid exception entry */if(!user_mode(regs)&&(address>=TASK_SIZE))
@@ -12,67 +12,6 @@#include <asm/ppc_asm.h>#include <asm/asm-offsets.h>-_GLOBAL(xmon_setjmp)-mflrr0-PPC_STLr0,0(r3)-PPC_STLr1,SZL(r3)-PPC_STLr2,2*SZL(r3)-mfcrr0-PPC_STLr0,3*SZL(r3)-PPC_STLr13,4*SZL(r3)-PPC_STLr14,5*SZL(r3)-PPC_STLr15,6*SZL(r3)-PPC_STLr16,7*SZL(r3)-PPC_STLr17,8*SZL(r3)-PPC_STLr18,9*SZL(r3)-PPC_STLr19,10*SZL(r3)-PPC_STLr20,11*SZL(r3)-PPC_STLr21,12*SZL(r3)-PPC_STLr22,13*SZL(r3)-PPC_STLr23,14*SZL(r3)-PPC_STLr24,15*SZL(r3)-PPC_STLr25,16*SZL(r3)-PPC_STLr26,17*SZL(r3)-PPC_STLr27,18*SZL(r3)-PPC_STLr28,19*SZL(r3)-PPC_STLr29,20*SZL(r3)-PPC_STLr30,21*SZL(r3)-PPC_STLr31,22*SZL(r3)-lir3,0-blr--_GLOBAL(xmon_longjmp)-PPC_LCMPIr4,0-bne1f-lir4,1-1:PPC_LLr13,4*SZL(r3)-PPC_LLr14,5*SZL(r3)-PPC_LLr15,6*SZL(r3)-PPC_LLr16,7*SZL(r3)-PPC_LLr17,8*SZL(r3)-PPC_LLr18,9*SZL(r3)-PPC_LLr19,10*SZL(r3)-PPC_LLr20,11*SZL(r3)-PPC_LLr21,12*SZL(r3)-PPC_LLr22,13*SZL(r3)-PPC_LLr23,14*SZL(r3)-PPC_LLr24,15*SZL(r3)-PPC_LLr25,16*SZL(r3)-PPC_LLr26,17*SZL(r3)-PPC_LLr27,18*SZL(r3)-PPC_LLr28,19*SZL(r3)-PPC_LLr29,20*SZL(r3)-PPC_LLr30,21*SZL(r3)-PPC_LLr31,22*SZL(r3)-PPC_LLr0,3*SZL(r3)-mtcrf0x38,r0-PPC_LLr0,0(r3)-PPC_LLr1,SZL(r3)-PPC_LLr2,2*SZL(r3)-mtlrr0-mrr3,r4-blr-/**Grabtheregistervaluesastheyarenow.*Thiswon't do a particularily good job because we really
From: Michael Neuling <hidden> Date: 2008-01-18 04:50:30
This adds hooks into the default_machine_crash_shutdown so drivers can
register a function to be run in the first kernel before we hand off
to the second kernel. This should only be used in exceptional
circumstances, like where the device can't be reset in the second
kernel alone (as is the case with eHEA). To emphasize this, the
number of handles allowed to be registered is currently #def to 1.
This uses the setjmp/longjmp code to call out to the registered hooks,
so any bogus exceptions we encounter will hopefully be recoverable.
Tested with bogus data and instruction exceptions.
Signed-off-by: Michael Neuling <redacted>
---
arch/powerpc/kernel/crash.c | 106 +++++++++++++++++++++++++++++++++++++++++---
include/asm-powerpc/kexec.h | 3 +
2 files changed, 104 insertions(+), 5 deletions(-)
Index: linux-2.6-ozlabs/arch/powerpc/kernel/crash.c
===================================================================