Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e0d5c45 authored by Helge Deller's avatar Helge Deller
Browse files

parisc: Consolidate unwind initialization calls



Signed-off-by: default avatarHelge Deller <deller@gmx.de>
parent 54c770da
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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;