فهرست منبع

parisc: Consolidate unwind initialization calls

Signed-off-by: Helge Deller <deller@gmx.de>
Helge Deller 7 سال پیش
والد
کامیت
9e0d5c451f
4فایلهای تغییر یافته به همراه36 افزوده شده و 57 حذف شده
  1. 4 2
      arch/parisc/include/asm/unwind.h
  2. 1 14
      arch/parisc/kernel/stacktrace.c
  3. 5 30
      arch/parisc/kernel/traps.c
  4. 26 11
      arch/parisc/kernel/unwind.c

+ 4 - 2
arch/parisc/include/asm/unwind.h

@@ -73,8 +73,10 @@ unwind_table_remove(struct unwind_table *table);
 
 void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, 
 		       struct pt_regs *regs);
-void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t);
-void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs);
+void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info,
+			struct task_struct *t);
+void unwind_frame_init_task(struct unwind_frame_info *info,
+			struct task_struct *task, struct pt_regs *regs);
 int unwind_once(struct unwind_frame_info *info);
 int unwind_to_user(struct unwind_frame_info *info);
 

+ 1 - 14
arch/parisc/kernel/stacktrace.c

@@ -16,20 +16,7 @@ static void dump_trace(struct task_struct *task, struct stack_trace *trace)
 {
 	struct unwind_frame_info info;
 
-	/* initialize unwind info */
-	if (task == current) {
-		unsigned long sp;
-		struct pt_regs r;
-HERE:
-		asm volatile ("copy %%r30, %0" : "=r"(sp));
-		memset(&r, 0, sizeof(struct pt_regs));
-		r.iaoq[0] = (unsigned long)&&HERE;
-		r.gr[2] = (unsigned long)__builtin_return_address(0);
-		r.gr[30] = sp;
-		unwind_frame_init(&info, task, &r);
-	} else {
-		unwind_frame_init_from_blocked_task(&info, task);
-	}
+	unwind_frame_init_task(&info, task, NULL);
 
 	/* unwind stack and save entries in stack_trace struct */
 	trace->nr_entries = 0;

+ 5 - 30
arch/parisc/kernel/traps.c

@@ -45,7 +45,7 @@
 
 #include "../math-emu/math-emu.h"	/* for handle_fpe() */
 
-static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
+static void parisc_show_stack(struct task_struct *task,
 	struct pt_regs *regs);
 
 static int printbinary(char *buf, unsigned long x, int nbits)
@@ -152,7 +152,7 @@ void show_regs(struct pt_regs *regs)
 		printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
 		printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
 
-		parisc_show_stack(current, NULL, regs);
+		parisc_show_stack(current, regs);
 	}
 }
 
@@ -185,44 +185,19 @@ static void do_show_stack(struct unwind_frame_info *info)
 	printk(KERN_CRIT "\n");
 }
 
-static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
+static void parisc_show_stack(struct task_struct *task,
 	struct pt_regs *regs)
 {
 	struct unwind_frame_info info;
-	struct task_struct *t;
 
-	t = task ? task : current;
-	if (regs) {
-		unwind_frame_init(&info, t, regs);
-		goto show_stack;
-	}
-
-	if (t == current) {
-		unsigned long sp;
-
-HERE:
-		asm volatile ("copy %%r30, %0" : "=r"(sp));
-		{
-			struct pt_regs r;
-
-			memset(&r, 0, sizeof(struct pt_regs));
-			r.iaoq[0] = (unsigned long)&&HERE;
-			r.gr[2] = (unsigned long)__builtin_return_address(0);
-			r.gr[30] = sp;
-
-			unwind_frame_init(&info, current, &r);
-		}
-	} else {
-		unwind_frame_init_from_blocked_task(&info, t);
-	}
+	unwind_frame_init_task(&info, task, regs);
 
-show_stack:
 	do_show_stack(&info);
 }
 
 void show_stack(struct task_struct *t, unsigned long *sp)
 {
-	return parisc_show_stack(t, sp, NULL);
+	parisc_show_stack(t, NULL);
 }
 
 int is_valid_bugaddr(unsigned long iaoq)

+ 26 - 11
arch/parisc/kernel/unwind.c

@@ -403,9 +403,31 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
 	kfree(r2);
 }
 
-void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs)
+#define get_parisc_stackpointer() ({ \
+	unsigned long sp; \
+	__asm__("copy %%r30, %0" : "=r"(sp)); \
+	(sp); \
+})
+
+void unwind_frame_init_task(struct unwind_frame_info *info,
+	struct task_struct *task, struct pt_regs *regs)
 {
-	unwind_frame_init(info, current, regs);
+	task = task ? task : current;
+
+	if (task == current) {
+		struct pt_regs r;
+
+		if (!regs) {
+			memset(&r, 0, sizeof(r));
+			r.iaoq[0] =  _THIS_IP_;
+			r.gr[2] = _RET_IP_;
+			r.gr[30] = get_parisc_stackpointer();
+			regs = &r;
+		}
+		unwind_frame_init(info, task, &r);
+	} else {
+		unwind_frame_init_from_blocked_task(info, task);
+	}
 }
 
 int unwind_once(struct unwind_frame_info *next_frame)
@@ -442,19 +464,12 @@ int unwind_to_user(struct unwind_frame_info *info)
 unsigned long return_address(unsigned int level)
 {
 	struct unwind_frame_info info;
-	struct pt_regs r;
-	unsigned long sp;
 
 	/* initialize unwind info */
-	asm volatile ("copy %%r30, %0" : "=r"(sp));
-	memset(&r, 0, sizeof(struct pt_regs));
-	r.iaoq[0] = _THIS_IP_;
-	r.gr[2] = _RET_IP_;
-	r.gr[30] = sp;
-	unwind_frame_init(&info, current, &r);
+	unwind_frame_init_task(&info, current, NULL);
 
 	/* unwind stack */
-	++level;
+	level += 2;
 	do {
 		if (unwind_once(&info) < 0 || info.ip == 0)
 			return 0;