All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 20/23] Make register values available to Sparc panic notifiers
@ 2010-04-12  6:07 ` David VomLehn
  0 siblings, 0 replies; 3+ messages in thread
From: David VomLehn @ 2010-04-12  6:07 UTC (permalink / raw)
  To: to, linux-arch@vger.kernel.org, linux-arch; +Cc: akpm, linux-kernel, maint_arch

The save_ptregs() function has not been tested or even built. I will need
help to complete this.

Signed-off-by: David VomLehn <dvomlehn@cisco.com>
---
 arch/sparc/include/asm/ptrace.h |  161 +++++++++++++++++++++++++++++++++++++++
 arch/sparc/kernel/traps_32.c    |    3 +-
 arch/sparc/kernel/traps_64.c    |   11 ++-
 3 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index 30b0b79..7303ebf 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -420,6 +420,167 @@ extern void show_regs(struct pt_regs *);
 #define GR_SNAP_THREAD	0x30
 #define GR_SNAP_PAD1	0x38
 
+/* Macros for saving the contents of registers and for the output constraint
+ * for those registers */
+#include <linux/ptreg.h>
+
+#if defined(__sparc__) && defined(__arch64__)
+#define PTREG_SAVE(r, name)		"stx	" #r ", %[" #name "]\n"
+#else
+#define PTREG_SAVE(r, name)		"st	" #r ", %[" #name "]\n"
+#endif
+
+#define PTREG_SAVE_U(i)			PTREG_SAVE_IDX(%g, u_regs, i)
+
+#define PTREG_OUT_U(regs, i)		PTREG_OUT_IDX(regs, %g, u_regs, i)
+
+#define arch_has_save_ptregs	1
+
+/**
+ * save_ptregs - save processor registers for backtracing
+ * @regs:	Pointer to &struct pt_regs structure in which to save the
+ *		registers
+ *
+ * Returns a constant pointer to @regs.
+ *
+ * This function must be called first in a function. There must be no
+ * auto variables defined that are initialized before calling this function.
+ */
+#if defined(__sparc__) && defined(__arch64__)
+static __always_inline
+const struct pt_regs *save_ptregs(struct pt_regs *regs)
+{
+	__asm__ __volatile__ (
+			PTREG_SAVE_U(0)
+			PTREG_SAVE_U(1)
+			PTREG_SAVE_U(2)
+			PTREG_SAVE_U(3)
+			PTREG_SAVE_U(4)
+			PTREG_SAVE_U(5)
+			PTREG_SAVE_U(6)
+			PTREG_SAVE_U(7)
+			PTREG_SAVE_U(8)
+			PTREG_SAVE_U(9)
+			PTREG_SAVE_U(10)
+			PTREG_SAVE_U(11)
+			PTREG_SAVE_U(12)
+			PTREG_SAVE_U(13)
+			PTREG_SAVE_U(14)
+			PTREG_SAVE_U(15)
+			PTREG_SAVE(tstate, tstate)
+			PTREG_SAVE(tpc, tpc)
+			PTREG_SAVE(tnpc, tnpc)
+			PTREG_SAVE(y, y)
+			PTREG_SAVE(magic, magic)
+		/*
+		 * The current location is the one for which the register
+		 * values are correct, even if some had been modified on
+		 * function entry. So, the current location is the value to
+		 * save as the execution address.
+		 */
+		 "1:\n"
+			 "sethi	%%hi(1b), %g7\n"
+			"or	%g7, %lo(1b), %g7\n"
+			PTREG_SAVE(%g7, tpc)
+	:
+		PTREG_OUT_U(0),
+		PTREG_OUT_U(1),
+		PTREG_OUT_U(2),
+		PTREG_OUT_U(3),
+		PTREG_OUT_U(4),
+		PTREG_OUT_U(5),
+		PTREG_OUT_U(6),
+		PTREG_OUT_U(7),
+		PTREG_OUT_U(8),
+		PTREG_OUT_U(9),
+		PTREG_OUT_U(10),
+		PTREG_OUT_U(11),
+		PTREG_OUT_U(12),
+		PTREG_OUT_U(13),
+		PTREG_OUT_U(14),
+		PTREG_OUT_U(15),
+		PTREG_OUT(regs, tstate, tstate),
+		PTREG_OUT(regs, tpc, tpc),
+		PTREG_OUT(regs, tnpc, tnpc),
+		PTREG_OUT(regs, y, y),
+		PTREG_OUT(regs, magic, magic)
+	:
+		"g7"
+	);
+
+	return regs;
+}
+#else
+/**
+ * save_ptregs - save processor registers for backtracing
+ * @regs:	Pointer to &struct pt_regs structure in which to save the
+ *		registers
+ *
+ * Returns a constant pointer to @regs.
+ *
+ * This function must be called first in a function. There must be no
+ * auto variables defined that are initialized before calling this function.
+ */
+static __always_inline
+const struct pt_regs *save_ptregs(struct pt_regs *regs)
+{
+	__asm__ __volatile__ (
+			PTREG_SAVE_U(0)
+			PTREG_SAVE_U(1)
+			PTREG_SAVE_U(2)
+			PTREG_SAVE_U(3)
+			PTREG_SAVE_U(4)
+			PTREG_SAVE_U(5)
+			PTREG_SAVE_U(6)
+			PTREG_SAVE_U(7)
+			PTREG_SAVE_U(8)
+			PTREG_SAVE_U(9)
+			PTREG_SAVE_U(10)
+			PTREG_SAVE_U(11)
+			PTREG_SAVE_U(12)
+			PTREG_SAVE_U(13)
+			PTREG_SAVE_U(14)
+			PTREG_SAVE_U(15)
+			PTREG_SAVE(psr, psr)
+			PTREG_SAVE(pc, pc)
+			PTREG_SAVE(npc, npc)
+			PTREG_SAVE(y, y)
+			PTREG_SAVE(magic, magic)
+		/*
+		 * The current location is the one for which the register
+		 * values are correct, even if some had been modified on
+		 * function entry. So, the current location is the value to
+		 * save as the execution address.
+		 */
+	:
+		PTREG_OUT_U(0),
+		PTREG_OUT_U(1),
+		PTREG_OUT_U(2),
+		PTREG_OUT_U(3),
+		PTREG_OUT_U(4),
+		PTREG_OUT_U(5),
+		PTREG_OUT_U(6),
+		PTREG_OUT_U(7),
+		PTREG_OUT_U(8),
+		PTREG_OUT_U(9),
+		PTREG_OUT_U(10),
+		PTREG_OUT_U(11),
+		PTREG_OUT_U(12),
+		PTREG_OUT_U(13),
+		PTREG_OUT_U(14),
+		PTREG_OUT_U(15),
+		PTREG_OUT(regs, psr, psr),
+		PTREG_OUT(regs, pc, pc),
+		PTREG_OUT(regs, npc, npc),
+		PTREG_OUT(regs, y, y),
+		PTREG_OUT(regs, magic, magic)
+	:
+	);
+
+	return regs;
+}
+#endif /* (defined(__sparc__) && defined(__arch64__)) */
+
 #endif  /*  __KERNEL__  */
 
 /* Stuff for the ptrace system call */
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index c0490c7..9b41e2f 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -353,7 +353,8 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc
 	       pc, npc, psr);
 #endif
 	if(psr & PSR_PS)
-		panic("Tell me what a watchpoint trap is, and I'll then deal "
+		panic_with_regs(regs,
+			"Tell me what a watchpoint trap is, and I'll then deal "
 		      "with such a beast...");
 }
 
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 10f7bb9..c4035d3 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -1347,7 +1347,7 @@ void cheetah_fecc_handler(struct pt_regs *regs, unsigned long afsr, unsigned lon
 	cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
 
 	if (!recoverable)
-		panic("Irrecoverable Fast-ECC error trap.\n");
+		panic_with_regs(regs, "Irrecoverable Fast-ECC error trap.\n");
 
 	/* Flush E-cache to kick the error trap handlers out. */
 	cheetah_flush_ecache();
@@ -1525,7 +1525,8 @@ void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long
 	cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
 
 	if (!recoverable)
-		panic("Irrecoverable Correctable-ECC error trap.\n");
+		panic_with_regs(regs,
+			"Irrecoverable Correctable-ECC error trap.\n");
 }
 
 void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar)
@@ -1712,7 +1713,7 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned
 	}
 
 	if (!recoverable)
-		panic("Irrecoverable deferred error trap.\n");
+		panic_with_regs(regs, "Irrecoverable deferred error trap.\n");
 }
 
 /* Handle a D/I cache parity error trap.  TYPE is encoded as:
@@ -1747,7 +1748,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
 		       (type & 0x1) ? 'I' : 'D',
 		       regs->tpc);
 		printk(KERN_EMERG "TPC<%pS>\n", (void *) regs->tpc);
-		panic("Irrecoverable Cheetah+ parity error.");
+		panic_with_regs(regs, "Irrecoverable Cheetah+ parity error.");
 	}
 
 	printk(KERN_WARNING "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n",
@@ -1934,7 +1935,7 @@ void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset)
 			KERN_EMERG "NON-RESUMABLE ERROR",
 			&sun4v_nonresum_oflow_cnt);
 
-	panic("Non-resumable error.");
+	panic_with_regs(regs, "Non-resumable error.");
 }
 
 /* If we try to printk() we'll probably make matters worse, by trying

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 20/23] Make register values available to Sparc panic notifiers
@ 2010-04-12  6:07 ` David VomLehn
  0 siblings, 0 replies; 3+ messages in thread
From: David VomLehn @ 2010-04-12  6:07 UTC (permalink / raw)
  To: to, linux-arch@vger.kernel.org; +Cc: akpm, linux-kernel, maint_arch

The save_ptregs() function has not been tested or even built. I will need
help to complete this.

Signed-off-by: David VomLehn <dvomlehn@cisco.com>
---
 arch/sparc/include/asm/ptrace.h |  161 +++++++++++++++++++++++++++++++++++++++
 arch/sparc/kernel/traps_32.c    |    3 +-
 arch/sparc/kernel/traps_64.c    |   11 ++-
 3 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index 30b0b79..7303ebf 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -420,6 +420,167 @@ extern void show_regs(struct pt_regs *);
 #define GR_SNAP_THREAD	0x30
 #define GR_SNAP_PAD1	0x38
 
+/* Macros for saving the contents of registers and for the output constraint
+ * for those registers */
+#include <linux/ptreg.h>
+
+#if defined(__sparc__) && defined(__arch64__)
+#define PTREG_SAVE(r, name)		"stx	" #r ", %[" #name "]\n"
+#else
+#define PTREG_SAVE(r, name)		"st	" #r ", %[" #name "]\n"
+#endif
+
+#define PTREG_SAVE_U(i)			PTREG_SAVE_IDX(%g, u_regs, i)
+
+#define PTREG_OUT_U(regs, i)		PTREG_OUT_IDX(regs, %g, u_regs, i)
+
+#define arch_has_save_ptregs	1
+
+/**
+ * save_ptregs - save processor registers for backtracing
+ * @regs:	Pointer to &struct pt_regs structure in which to save the
+ *		registers
+ *
+ * Returns a constant pointer to @regs.
+ *
+ * This function must be called first in a function. There must be no
+ * auto variables defined that are initialized before calling this function.
+ */
+#if defined(__sparc__) && defined(__arch64__)
+static __always_inline
+const struct pt_regs *save_ptregs(struct pt_regs *regs)
+{
+	__asm__ __volatile__ (
+			PTREG_SAVE_U(0)
+			PTREG_SAVE_U(1)
+			PTREG_SAVE_U(2)
+			PTREG_SAVE_U(3)
+			PTREG_SAVE_U(4)
+			PTREG_SAVE_U(5)
+			PTREG_SAVE_U(6)
+			PTREG_SAVE_U(7)
+			PTREG_SAVE_U(8)
+			PTREG_SAVE_U(9)
+			PTREG_SAVE_U(10)
+			PTREG_SAVE_U(11)
+			PTREG_SAVE_U(12)
+			PTREG_SAVE_U(13)
+			PTREG_SAVE_U(14)
+			PTREG_SAVE_U(15)
+			PTREG_SAVE(tstate, tstate)
+			PTREG_SAVE(tpc, tpc)
+			PTREG_SAVE(tnpc, tnpc)
+			PTREG_SAVE(y, y)
+			PTREG_SAVE(magic, magic)
+		/*
+		 * The current location is the one for which the register
+		 * values are correct, even if some had been modified on
+		 * function entry. So, the current location is the value to
+		 * save as the execution address.
+		 */
+		 "1:\n"
+			 "sethi	%%hi(1b), %g7\n"
+			"or	%g7, %lo(1b), %g7\n"
+			PTREG_SAVE(%g7, tpc)
+	:
+		PTREG_OUT_U(0),
+		PTREG_OUT_U(1),
+		PTREG_OUT_U(2),
+		PTREG_OUT_U(3),
+		PTREG_OUT_U(4),
+		PTREG_OUT_U(5),
+		PTREG_OUT_U(6),
+		PTREG_OUT_U(7),
+		PTREG_OUT_U(8),
+		PTREG_OUT_U(9),
+		PTREG_OUT_U(10),
+		PTREG_OUT_U(11),
+		PTREG_OUT_U(12),
+		PTREG_OUT_U(13),
+		PTREG_OUT_U(14),
+		PTREG_OUT_U(15),
+		PTREG_OUT(regs, tstate, tstate),
+		PTREG_OUT(regs, tpc, tpc),
+		PTREG_OUT(regs, tnpc, tnpc),
+		PTREG_OUT(regs, y, y),
+		PTREG_OUT(regs, magic, magic)
+	:
+		"g7"
+	);
+
+	return regs;
+}
+#else
+/**
+ * save_ptregs - save processor registers for backtracing
+ * @regs:	Pointer to &struct pt_regs structure in which to save the
+ *		registers
+ *
+ * Returns a constant pointer to @regs.
+ *
+ * This function must be called first in a function. There must be no
+ * auto variables defined that are initialized before calling this function.
+ */
+static __always_inline
+const struct pt_regs *save_ptregs(struct pt_regs *regs)
+{
+	__asm__ __volatile__ (
+			PTREG_SAVE_U(0)
+			PTREG_SAVE_U(1)
+			PTREG_SAVE_U(2)
+			PTREG_SAVE_U(3)
+			PTREG_SAVE_U(4)
+			PTREG_SAVE_U(5)
+			PTREG_SAVE_U(6)
+			PTREG_SAVE_U(7)
+			PTREG_SAVE_U(8)
+			PTREG_SAVE_U(9)
+			PTREG_SAVE_U(10)
+			PTREG_SAVE_U(11)
+			PTREG_SAVE_U(12)
+			PTREG_SAVE_U(13)
+			PTREG_SAVE_U(14)
+			PTREG_SAVE_U(15)
+			PTREG_SAVE(psr, psr)
+			PTREG_SAVE(pc, pc)
+			PTREG_SAVE(npc, npc)
+			PTREG_SAVE(y, y)
+			PTREG_SAVE(magic, magic)
+		/*
+		 * The current location is the one for which the register
+		 * values are correct, even if some had been modified on
+		 * function entry. So, the current location is the value to
+		 * save as the execution address.
+		 */
+	:
+		PTREG_OUT_U(0),
+		PTREG_OUT_U(1),
+		PTREG_OUT_U(2),
+		PTREG_OUT_U(3),
+		PTREG_OUT_U(4),
+		PTREG_OUT_U(5),
+		PTREG_OUT_U(6),
+		PTREG_OUT_U(7),
+		PTREG_OUT_U(8),
+		PTREG_OUT_U(9),
+		PTREG_OUT_U(10),
+		PTREG_OUT_U(11),
+		PTREG_OUT_U(12),
+		PTREG_OUT_U(13),
+		PTREG_OUT_U(14),
+		PTREG_OUT_U(15),
+		PTREG_OUT(regs, psr, psr),
+		PTREG_OUT(regs, pc, pc),
+		PTREG_OUT(regs, npc, npc),
+		PTREG_OUT(regs, y, y),
+		PTREG_OUT(regs, magic, magic)
+	:
+	);
+
+	return regs;
+}
+#endif /* (defined(__sparc__) && defined(__arch64__)) */
+
 #endif  /*  __KERNEL__  */
 
 /* Stuff for the ptrace system call */
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index c0490c7..9b41e2f 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -353,7 +353,8 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc
 	       pc, npc, psr);
 #endif
 	if(psr & PSR_PS)
-		panic("Tell me what a watchpoint trap is, and I'll then deal "
+		panic_with_regs(regs,
+			"Tell me what a watchpoint trap is, and I'll then deal "
 		      "with such a beast...");
 }
 
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 10f7bb9..c4035d3 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -1347,7 +1347,7 @@ void cheetah_fecc_handler(struct pt_regs *regs, unsigned long afsr, unsigned lon
 	cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
 
 	if (!recoverable)
-		panic("Irrecoverable Fast-ECC error trap.\n");
+		panic_with_regs(regs, "Irrecoverable Fast-ECC error trap.\n");
 
 	/* Flush E-cache to kick the error trap handlers out. */
 	cheetah_flush_ecache();
@@ -1525,7 +1525,8 @@ void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long
 	cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
 
 	if (!recoverable)
-		panic("Irrecoverable Correctable-ECC error trap.\n");
+		panic_with_regs(regs,
+			"Irrecoverable Correctable-ECC error trap.\n");
 }
 
 void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar)
@@ -1712,7 +1713,7 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned
 	}
 
 	if (!recoverable)
-		panic("Irrecoverable deferred error trap.\n");
+		panic_with_regs(regs, "Irrecoverable deferred error trap.\n");
 }
 
 /* Handle a D/I cache parity error trap.  TYPE is encoded as:
@@ -1747,7 +1748,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
 		       (type & 0x1) ? 'I' : 'D',
 		       regs->tpc);
 		printk(KERN_EMERG "TPC<%pS>\n", (void *) regs->tpc);
-		panic("Irrecoverable Cheetah+ parity error.");
+		panic_with_regs(regs, "Irrecoverable Cheetah+ parity error.");
 	}
 
 	printk(KERN_WARNING "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n",
@@ -1934,7 +1935,7 @@ void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset)
 			KERN_EMERG "NON-RESUMABLE ERROR",
 			&sun4v_nonresum_oflow_cnt);
 
-	panic("Non-resumable error.");
+	panic_with_regs(regs, "Non-resumable error.");
 }
 
 /* If we try to printk() we'll probably make matters worse, by trying

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 20/23] Make register values available to Sparc panic notifiers
@ 2010-04-12  6:04 David VomLehn
  0 siblings, 0 replies; 3+ messages in thread
From: David VomLehn @ 2010-04-12  6:04 UTC (permalink / raw)
  To: to, linux_arch, linux_arch; +Cc: akpm, linux-kernel, maint_arch

The save_ptregs() function has not been tested or even built. I will need
help to complete this.

Signed-off-by: David VomLehn <dvomlehn@cisco.com>
---
 arch/sparc/include/asm/ptrace.h |  161 +++++++++++++++++++++++++++++++++++++++
 arch/sparc/kernel/traps_32.c    |    3 +-
 arch/sparc/kernel/traps_64.c    |   11 ++-
 3 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index 30b0b79..7303ebf 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -420,6 +420,167 @@ extern void show_regs(struct pt_regs *);
 #define GR_SNAP_THREAD	0x30
 #define GR_SNAP_PAD1	0x38
 
+/* Macros for saving the contents of registers and for the output constraint
+ * for those registers */
+#include <linux/ptreg.h>
+
+#if defined(__sparc__) && defined(__arch64__)
+#define PTREG_SAVE(r, name)		"stx	" #r ", %[" #name "]\n"
+#else
+#define PTREG_SAVE(r, name)		"st	" #r ", %[" #name "]\n"
+#endif
+
+#define PTREG_SAVE_U(i)			PTREG_SAVE_IDX(%g, u_regs, i)
+
+#define PTREG_OUT_U(regs, i)		PTREG_OUT_IDX(regs, %g, u_regs, i)
+
+#define arch_has_save_ptregs	1
+
+/**
+ * save_ptregs - save processor registers for backtracing
+ * @regs:	Pointer to &struct pt_regs structure in which to save the
+ *		registers
+ *
+ * Returns a constant pointer to @regs.
+ *
+ * This function must be called first in a function. There must be no
+ * auto variables defined that are initialized before calling this function.
+ */
+#if defined(__sparc__) && defined(__arch64__)
+static __always_inline
+const struct pt_regs *save_ptregs(struct pt_regs *regs)
+{
+	__asm__ __volatile__ (
+			PTREG_SAVE_U(0)
+			PTREG_SAVE_U(1)
+			PTREG_SAVE_U(2)
+			PTREG_SAVE_U(3)
+			PTREG_SAVE_U(4)
+			PTREG_SAVE_U(5)
+			PTREG_SAVE_U(6)
+			PTREG_SAVE_U(7)
+			PTREG_SAVE_U(8)
+			PTREG_SAVE_U(9)
+			PTREG_SAVE_U(10)
+			PTREG_SAVE_U(11)
+			PTREG_SAVE_U(12)
+			PTREG_SAVE_U(13)
+			PTREG_SAVE_U(14)
+			PTREG_SAVE_U(15)
+			PTREG_SAVE(tstate, tstate)
+			PTREG_SAVE(tpc, tpc)
+			PTREG_SAVE(tnpc, tnpc)
+			PTREG_SAVE(y, y)
+			PTREG_SAVE(magic, magic)
+		/*
+		 * The current location is the one for which the register
+		 * values are correct, even if some had been modified on
+		 * function entry. So, the current location is the value to
+		 * save as the execution address.
+		 */
+		 "1:\n"
+			 "sethi	%%hi(1b), %g7\n"
+			"or	%g7, %lo(1b), %g7\n"
+			PTREG_SAVE(%g7, tpc)
+	:
+		PTREG_OUT_U(0),
+		PTREG_OUT_U(1),
+		PTREG_OUT_U(2),
+		PTREG_OUT_U(3),
+		PTREG_OUT_U(4),
+		PTREG_OUT_U(5),
+		PTREG_OUT_U(6),
+		PTREG_OUT_U(7),
+		PTREG_OUT_U(8),
+		PTREG_OUT_U(9),
+		PTREG_OUT_U(10),
+		PTREG_OUT_U(11),
+		PTREG_OUT_U(12),
+		PTREG_OUT_U(13),
+		PTREG_OUT_U(14),
+		PTREG_OUT_U(15),
+		PTREG_OUT(regs, tstate, tstate),
+		PTREG_OUT(regs, tpc, tpc),
+		PTREG_OUT(regs, tnpc, tnpc),
+		PTREG_OUT(regs, y, y),
+		PTREG_OUT(regs, magic, magic)
+	:
+		"g7"
+	);
+
+	return regs;
+}
+#else
+/**
+ * save_ptregs - save processor registers for backtracing
+ * @regs:	Pointer to &struct pt_regs structure in which to save the
+ *		registers
+ *
+ * Returns a constant pointer to @regs.
+ *
+ * This function must be called first in a function. There must be no
+ * auto variables defined that are initialized before calling this function.
+ */
+static __always_inline
+const struct pt_regs *save_ptregs(struct pt_regs *regs)
+{
+	__asm__ __volatile__ (
+			PTREG_SAVE_U(0)
+			PTREG_SAVE_U(1)
+			PTREG_SAVE_U(2)
+			PTREG_SAVE_U(3)
+			PTREG_SAVE_U(4)
+			PTREG_SAVE_U(5)
+			PTREG_SAVE_U(6)
+			PTREG_SAVE_U(7)
+			PTREG_SAVE_U(8)
+			PTREG_SAVE_U(9)
+			PTREG_SAVE_U(10)
+			PTREG_SAVE_U(11)
+			PTREG_SAVE_U(12)
+			PTREG_SAVE_U(13)
+			PTREG_SAVE_U(14)
+			PTREG_SAVE_U(15)
+			PTREG_SAVE(psr, psr)
+			PTREG_SAVE(pc, pc)
+			PTREG_SAVE(npc, npc)
+			PTREG_SAVE(y, y)
+			PTREG_SAVE(magic, magic)
+		/*
+		 * The current location is the one for which the register
+		 * values are correct, even if some had been modified on
+		 * function entry. So, the current location is the value to
+		 * save as the execution address.
+		 */
+	:
+		PTREG_OUT_U(0),
+		PTREG_OUT_U(1),
+		PTREG_OUT_U(2),
+		PTREG_OUT_U(3),
+		PTREG_OUT_U(4),
+		PTREG_OUT_U(5),
+		PTREG_OUT_U(6),
+		PTREG_OUT_U(7),
+		PTREG_OUT_U(8),
+		PTREG_OUT_U(9),
+		PTREG_OUT_U(10),
+		PTREG_OUT_U(11),
+		PTREG_OUT_U(12),
+		PTREG_OUT_U(13),
+		PTREG_OUT_U(14),
+		PTREG_OUT_U(15),
+		PTREG_OUT(regs, psr, psr),
+		PTREG_OUT(regs, pc, pc),
+		PTREG_OUT(regs, npc, npc),
+		PTREG_OUT(regs, y, y),
+		PTREG_OUT(regs, magic, magic)
+	:
+	);
+
+	return regs;
+}
+#endif /* (defined(__sparc__) && defined(__arch64__)) */
+
 #endif  /*  __KERNEL__  */
 
 /* Stuff for the ptrace system call */
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index c0490c7..9b41e2f 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -353,7 +353,8 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc
 	       pc, npc, psr);
 #endif
 	if(psr & PSR_PS)
-		panic("Tell me what a watchpoint trap is, and I'll then deal "
+		panic_with_regs(regs,
+			"Tell me what a watchpoint trap is, and I'll then deal "
 		      "with such a beast...");
 }
 
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 10f7bb9..c4035d3 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -1347,7 +1347,7 @@ void cheetah_fecc_handler(struct pt_regs *regs, unsigned long afsr, unsigned lon
 	cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
 
 	if (!recoverable)
-		panic("Irrecoverable Fast-ECC error trap.\n");
+		panic_with_regs(regs, "Irrecoverable Fast-ECC error trap.\n");
 
 	/* Flush E-cache to kick the error trap handlers out. */
 	cheetah_flush_ecache();
@@ -1525,7 +1525,8 @@ void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long
 	cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
 
 	if (!recoverable)
-		panic("Irrecoverable Correctable-ECC error trap.\n");
+		panic_with_regs(regs,
+			"Irrecoverable Correctable-ECC error trap.\n");
 }
 
 void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar)
@@ -1712,7 +1713,7 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned
 	}
 
 	if (!recoverable)
-		panic("Irrecoverable deferred error trap.\n");
+		panic_with_regs(regs, "Irrecoverable deferred error trap.\n");
 }
 
 /* Handle a D/I cache parity error trap.  TYPE is encoded as:
@@ -1747,7 +1748,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
 		       (type & 0x1) ? 'I' : 'D',
 		       regs->tpc);
 		printk(KERN_EMERG "TPC<%pS>\n", (void *) regs->tpc);
-		panic("Irrecoverable Cheetah+ parity error.");
+		panic_with_regs(regs, "Irrecoverable Cheetah+ parity error.");
 	}
 
 	printk(KERN_WARNING "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n",
@@ -1934,7 +1935,7 @@ void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset)
 			KERN_EMERG "NON-RESUMABLE ERROR",
 			&sun4v_nonresum_oflow_cnt);
 
-	panic("Non-resumable error.");
+	panic_with_regs(regs, "Non-resumable error.");
 }
 
 /* If we try to printk() we'll probably make matters worse, by trying

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-04-12  6:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-12  6:07 [PATCH 20/23] Make register values available to Sparc panic notifiers David VomLehn
2010-04-12  6:07 ` David VomLehn
  -- strict thread matches above, loose matches on Subject: below --
2010-04-12  6:04 David VomLehn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.