csky: Fixup get wrong psr value from phyical reg
[ Upstream commit 9c0e343d7654a329d1f9b53d253cbf7fb6eff85d ] 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>
This commit is contained in:
parent
c848e00e3b
commit
57615a8561
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user