| From 3c07f976a18afb68917f7f1b484944c2d89f4fd3 Mon Sep 17 00:00:00 2001 |
| From: Guo Ren <guoren@linux.alibaba.com> |
| Date: Tue, 31 Mar 2020 23:45:52 +0800 |
| Subject: [PATCH] csky: Fixup get wrong psr value from phyical reg |
| |
| commit 9c0e343d7654a329d1f9b53d253cbf7fb6eff85d upstream. |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/csky/include/asm/processor.h b/arch/csky/include/asm/processor.h |
| index 21e0bd5293dd..c6bcd7f7c720 100644 |
| --- a/arch/csky/include/asm/processor.h |
| +++ b/arch/csky/include/asm/processor.h |
| @@ -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; |
| diff --git a/arch/csky/kernel/traps.c b/arch/csky/kernel/traps.c |
| index f487a9b996ae..de903b18cd2a 100644 |
| --- a/arch/csky/kernel/traps.c |
| +++ b/arch/csky/kernel/traps.c |
| @@ -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: |
| @@ -128,6 +129,7 @@ asmlinkage void trap_c(struct pt_regs *regs) |
| sig = SIGTRAP; |
| break; |
| case VEC_ILLEGAL: |
| + tsk->thread.trap_no = vector; |
| #ifndef CONFIG_CPU_NO_USER_BKPT |
| if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT) |
| #endif |
| @@ -143,15 +145,19 @@ 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; |
| return fpu_fpe(regs); |
| case VEC_PRIV: |
| + tsk->thread.trap_no = vector; |
| if (fpu_libc_helper(regs)) |
| return; |
| #endif |
| @@ -159,5 +165,8 @@ asmlinkage void trap_c(struct pt_regs *regs) |
| sig = SIGSEGV; |
| break; |
| } |
| + |
| + tsk->thread.trap_no = vector; |
| + |
| send_sig(sig, current, 0); |
| } |
| diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c |
| index 18041f46ded1..01290c551071 100644 |
| --- a/arch/csky/mm/fault.c |
| +++ b/arch/csky/mm/fault.c |
| @@ -179,11 +179,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, |
| 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, current); |
| 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 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, |
| 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 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, |
| return; |
| |
| do_sigbus: |
| + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; |
| + |
| up_read(&mm->mmap_sem); |
| |
| /* Kernel mode? Handle exceptions or die */ |
| -- |
| 2.7.4 |
| |