1
0
Fork 0

csky: Fixup get wrong psr value from phyical reg

[ Upstream commit 9c0e343d76 ]

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: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
5.4-rM2-2.2.x-imx-squashed
Guo Ren 2020-03-31 23:45:52 +08:00 committed by Greg Kroah-Hartman
parent c848e00e3b
commit 57615a8561
3 changed files with 18 additions and 1 deletions

View File

@ -43,6 +43,7 @@ extern struct cpuinfo_csky cpu_data[];
struct thread_struct { struct thread_struct {
unsigned long ksp; /* kernel stack pointer */ unsigned long ksp; /* kernel stack pointer */
unsigned long sr; /* saved status register */ unsigned long sr; /* saved status register */
unsigned long trap_no; /* saved status register */
/* FPU regs */ /* FPU regs */
struct user_fp __aligned(16) user_fp; struct user_fp __aligned(16) user_fp;

View File

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

View File

@ -179,11 +179,14 @@ bad_area:
bad_area_nosemaphore: bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */ /* User mode accesses just cause a SIGSEGV */
if (user_mode(regs)) { if (user_mode(regs)) {
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
force_sig_fault(SIGSEGV, si_code, (void __user *)address); force_sig_fault(SIGSEGV, si_code, (void __user *)address);
return; return;
} }
no_context: no_context:
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
/* Are we prepared to handle this kernel fault? */ /* Are we prepared to handle this kernel fault? */
if (fixup_exception(regs)) if (fixup_exception(regs))
return; return;
@ -198,6 +201,8 @@ no_context:
die_if_kernel("Oops", regs, write); die_if_kernel("Oops", regs, write);
out_of_memory: out_of_memory:
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
/* /*
* We ran out of memory, call the OOM killer, and return the userspace * 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). * (which will retry the fault, or kill us if we got oom-killed).
@ -206,6 +211,8 @@ out_of_memory:
return; return;
do_sigbus: do_sigbus:
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
/* Kernel mode? Handle exceptions or die */ /* Kernel mode? Handle exceptions or die */