Commit 9c0e343d authored by Guo Ren's avatar Guo Ren
Browse files

csky: Fixup get wrong psr value from phyical reg



We should get psr value from regs->psr in stack, not directly get
it from phyiscal register then save the vector number in
tsk->trap_no.

Signed-off-by: default avatarGuo Ren <guoren@linux.alibaba.com>
parent dd7c983e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ extern struct cpuinfo_csky cpu_data[];
struct thread_struct {
	unsigned long  ksp;       /* kernel stack pointer */
	unsigned long  sr;        /* saved status register */
	unsigned long  trap_no;   /* saved status register */

	/* FPU regs */
	struct user_fp __aligned(16) user_fp;
+10 −1
Original line number Diff line number Diff line
@@ -115,8 +115,9 @@ asmlinkage void trap_c(struct pt_regs *regs)
	int sig;
	unsigned long vector;
	siginfo_t info;
	struct task_struct *tsk = current;

	vector = (mfcr("psr") >> 16) & 0xff;
	vector = (regs->sr >> 16) & 0xff;

	switch (vector) {
	case VEC_ZERODIV:
@@ -129,6 +130,7 @@ asmlinkage void trap_c(struct pt_regs *regs)
		sig = SIGTRAP;
		break;
	case VEC_ILLEGAL:
		tsk->thread.trap_no = vector;
		die_if_kernel("Kernel mode ILLEGAL", regs, vector);
#ifndef CONFIG_CPU_NO_USER_BKPT
		if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT)
@@ -146,16 +148,20 @@ asmlinkage void trap_c(struct pt_regs *regs)
		sig = SIGTRAP;
		break;
	case VEC_ACCESS:
		tsk->thread.trap_no = vector;
		return buserr(regs);
#ifdef CONFIG_CPU_NEED_SOFTALIGN
	case VEC_ALIGN:
		tsk->thread.trap_no = vector;
		return csky_alignment(regs);
#endif
#ifdef CONFIG_CPU_HAS_FPU
	case VEC_FPE:
		tsk->thread.trap_no = vector;
		die_if_kernel("Kernel mode FPE", regs, vector);
		return fpu_fpe(regs);
	case VEC_PRIV:
		tsk->thread.trap_no = vector;
		die_if_kernel("Kernel mode PRIV", regs, vector);
		if (fpu_libc_helper(regs))
			return;
@@ -164,5 +170,8 @@ asmlinkage void trap_c(struct pt_regs *regs)
		sig = SIGSEGV;
		break;
	}

	tsk->thread.trap_no = vector;

	send_sig(sig, current, 0);
}
+7 −0
Original line number Diff line number Diff line
@@ -179,11 +179,14 @@ bad_area:
bad_area_nosemaphore:
	/* User mode accesses just cause a SIGSEGV */
	if (user_mode(regs)) {
		tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
		force_sig_fault(SIGSEGV, si_code, (void __user *)address);
		return;
	}

no_context:
	tsk->thread.trap_no = (regs->sr >> 16) & 0xff;

	/* Are we prepared to handle this kernel fault? */
	if (fixup_exception(regs))
		return;
@@ -198,6 +201,8 @@ no_context:
	die_if_kernel("Oops", regs, write);

out_of_memory:
	tsk->thread.trap_no = (regs->sr >> 16) & 0xff;

	/*
	 * We ran out of memory, call the OOM killer, and return the userspace
	 * (which will retry the fault, or kill us if we got oom-killed).
@@ -206,6 +211,8 @@ out_of_memory:
	return;

do_sigbus:
	tsk->thread.trap_no = (regs->sr >> 16) & 0xff;

	up_read(&mm->mmap_sem);

	/* Kernel mode? Handle exceptions or die */