traps.c (0898782247ae533d1f4e47a06bc5d4870931b284) traps.c (9c0e343d7654a329d1f9b53d253cbf7fb6eff85d)
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4#include <linux/sched.h>
5#include <linux/signal.h>
6#include <linux/kernel.h>
7#include <linux/mm.h>
8#include <linux/module.h>

--- 101 unchanged lines hidden (view full) ---

110}
111
112#define USR_BKPT 0x1464
113asmlinkage void trap_c(struct pt_regs *regs)
114{
115 int sig;
116 unsigned long vector;
117 siginfo_t info;
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4#include <linux/sched.h>
5#include <linux/signal.h>
6#include <linux/kernel.h>
7#include <linux/mm.h>
8#include <linux/module.h>

--- 101 unchanged lines hidden (view full) ---

110}
111
112#define USR_BKPT 0x1464
113asmlinkage void trap_c(struct pt_regs *regs)
114{
115 int sig;
116 unsigned long vector;
117 siginfo_t info;
118 struct task_struct *tsk = current;
118
119
119 vector = (mfcr("psr") >> 16) & 0xff;
120 vector = (regs->sr >> 16) & 0xff;
120
121 switch (vector) {
122 case VEC_ZERODIV:
123 die_if_kernel("Kernel mode ZERO DIV", regs, vector);
124 sig = SIGFPE;
125 break;
126 /* ptrace */
127 case VEC_TRACE:
128 info.si_code = TRAP_TRACE;
129 sig = SIGTRAP;
130 break;
131 case VEC_ILLEGAL:
121
122 switch (vector) {
123 case VEC_ZERODIV:
124 die_if_kernel("Kernel mode ZERO DIV", regs, vector);
125 sig = SIGFPE;
126 break;
127 /* ptrace */
128 case VEC_TRACE:
129 info.si_code = TRAP_TRACE;
130 sig = SIGTRAP;
131 break;
132 case VEC_ILLEGAL:
133 tsk->thread.trap_no = vector;
132 die_if_kernel("Kernel mode ILLEGAL", regs, vector);
133#ifndef CONFIG_CPU_NO_USER_BKPT
134 if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT)
135#endif
136 {
137 sig = SIGILL;
138 break;
139 }
140 /* gdbserver breakpoint */
141 case VEC_TRAP1:
142 /* jtagserver breakpoint */
143 case VEC_BREAKPOINT:
144 die_if_kernel("Kernel mode BKPT", regs, vector);
145 info.si_code = TRAP_BRKPT;
146 sig = SIGTRAP;
147 break;
148 case VEC_ACCESS:
134 die_if_kernel("Kernel mode ILLEGAL", regs, vector);
135#ifndef CONFIG_CPU_NO_USER_BKPT
136 if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT)
137#endif
138 {
139 sig = SIGILL;
140 break;
141 }
142 /* gdbserver breakpoint */
143 case VEC_TRAP1:
144 /* jtagserver breakpoint */
145 case VEC_BREAKPOINT:
146 die_if_kernel("Kernel mode BKPT", regs, vector);
147 info.si_code = TRAP_BRKPT;
148 sig = SIGTRAP;
149 break;
150 case VEC_ACCESS:
151 tsk->thread.trap_no = vector;
149 return buserr(regs);
150#ifdef CONFIG_CPU_NEED_SOFTALIGN
151 case VEC_ALIGN:
152 return buserr(regs);
153#ifdef CONFIG_CPU_NEED_SOFTALIGN
154 case VEC_ALIGN:
155 tsk->thread.trap_no = vector;
152 return csky_alignment(regs);
153#endif
154#ifdef CONFIG_CPU_HAS_FPU
155 case VEC_FPE:
156 return csky_alignment(regs);
157#endif
158#ifdef CONFIG_CPU_HAS_FPU
159 case VEC_FPE:
160 tsk->thread.trap_no = vector;
156 die_if_kernel("Kernel mode FPE", regs, vector);
157 return fpu_fpe(regs);
158 case VEC_PRIV:
161 die_if_kernel("Kernel mode FPE", regs, vector);
162 return fpu_fpe(regs);
163 case VEC_PRIV:
164 tsk->thread.trap_no = vector;
159 die_if_kernel("Kernel mode PRIV", regs, vector);
160 if (fpu_libc_helper(regs))
161 return;
162#endif
163 default:
164 sig = SIGSEGV;
165 break;
166 }
165 die_if_kernel("Kernel mode PRIV", regs, vector);
166 if (fpu_libc_helper(regs))
167 return;
168#endif
169 default:
170 sig = SIGSEGV;
171 break;
172 }
173
174 tsk->thread.trap_no = vector;
175
167 send_sig(sig, current, 0);
168}
176 send_sig(sig, current, 0);
177}