76 #include <linux/signal.h>
78 #include <linux/sched.h>
80 #include <linux/perf_event.h>
84 #include <asm/byteorder.h>
87 #include <asm/uaccess.h>
89 #define STR(x) __STR(x)
97 #ifdef CONFIG_DEBUG_FS
98 static u32 unaligned_instructions;
101 #define unaligned_action UNALIGNED_ACTION_QUIET
105 static void emulate_load_store_insn(
struct pt_regs *
regs,
106 void __user *
addr,
unsigned int __user *
pc)
156 __asm__ __volatile__ (
".set\tnoat\n"
158 "1:\tlb\t%0, 0(%2)\n"
159 "2:\tlbu\t$1, 1(%2)\n\t"
162 "1:\tlb\t%0, 1(%2)\n"
163 "2:\tlbu\t$1, 0(%2)\n\t"
169 ".section\t.fixup,\"ax\"\n\t"
173 ".section\t__ex_table,\"a\"\n\t"
177 :
"=&r" (value),
"=r" (res)
178 :
"r" (addr),
"i" (-
EFAULT));
181 compute_return_epc(regs);
191 "1:\tlwl\t%0, (%2)\n"
192 "2:\tlwr\t%0, 3(%2)\n\t"
195 "1:\tlwl\t%0, 3(%2)\n"
196 "2:\tlwr\t%0, (%2)\n\t"
199 "3:\t.section\t.fixup,\"ax\"\n\t"
203 ".section\t__ex_table,\"a\"\n\t"
207 :
"=&r" (value),
"=r" (res)
208 :
"r" (addr),
"i" (-
EFAULT));
211 compute_return_epc(regs);
222 "1:\tlbu\t%0, 0(%2)\n"
223 "2:\tlbu\t$1, 1(%2)\n\t"
226 "1:\tlbu\t%0, 1(%2)\n"
227 "2:\tlbu\t$1, 0(%2)\n\t"
233 ".section\t.fixup,\"ax\"\n\t"
237 ".section\t__ex_table,\"a\"\n\t"
241 :
"=&r" (value),
"=r" (res)
242 :
"r" (addr),
"i" (-
EFAULT));
245 compute_return_epc(regs);
263 "1:\tlwl\t%0, (%2)\n"
264 "2:\tlwr\t%0, 3(%2)\n\t"
267 "1:\tlwl\t%0, 3(%2)\n"
268 "2:\tlwr\t%0, (%2)\n\t"
270 "dsll\t%0, %0, 32\n\t"
271 "dsrl\t%0, %0, 32\n\t"
273 "3:\t.section\t.fixup,\"ax\"\n\t"
277 ".section\t__ex_table,\"a\"\n\t"
281 :
"=&r" (value),
"=r" (res)
282 :
"r" (addr),
"i" (-
EFAULT));
285 compute_return_epc(regs);
307 "1:\tldl\t%0, (%2)\n"
308 "2:\tldr\t%0, 7(%2)\n\t"
311 "1:\tldl\t%0, 7(%2)\n"
312 "2:\tldr\t%0, (%2)\n\t"
315 "3:\t.section\t.fixup,\"ax\"\n\t"
319 ".section\t__ex_table,\"a\"\n\t"
323 :
"=&r" (value),
"=r" (res)
324 :
"r" (addr),
"i" (-
EFAULT));
327 compute_return_epc(regs);
339 value = regs->
regs[
insn.i_format.rt];
343 "1:\tsb\t%1, 1(%2)\n\t"
345 "2:\tsb\t$1, 0(%2)\n\t"
350 "1:\tsb\t%1, 0(%2)\n\t"
352 "2:\tsb\t$1, 1(%2)\n\t"
357 ".section\t.fixup,\"ax\"\n\t"
361 ".section\t__ex_table,\"a\"\n\t"
366 :
"r" (value),
"r" (addr),
"i" (-
EFAULT));
369 compute_return_epc(regs);
376 value = regs->
regs[
insn.i_format.rt];
380 "2:\tswr\t%1, 3(%2)\n\t"
383 "1:\tswl\t%1, 3(%2)\n"
384 "2:\tswr\t%1, (%2)\n\t"
388 ".section\t.fixup,\"ax\"\n\t"
392 ".section\t__ex_table,\"a\"\n\t"
397 :
"r" (value),
"r" (addr),
"i" (-
EFAULT));
400 compute_return_epc(regs);
415 value = regs->
regs[
insn.i_format.rt];
419 "2:\tsdr\t%1, 7(%2)\n\t"
422 "1:\tsdl\t%1, 7(%2)\n"
423 "2:\tsdr\t%1, (%2)\n\t"
427 ".section\t.fixup,\"ax\"\n\t"
431 ".section\t__ex_table,\"a\"\n\t"
436 :
"r" (value),
"r" (addr),
"i" (-
EFAULT));
439 compute_return_epc(regs);
484 #ifdef CONFIG_DEBUG_FS
485 unaligned_instructions++;
507 die_if_kernel(
"Unhandled kernel unaligned access or invalid instruction", regs);
525 pc = (
unsigned int __user *) exception_epc(regs);
526 if (
user_mode(regs) && !test_thread_flag(TIF_FIXADE))
554 #ifdef CONFIG_DEBUG_FS
556 static int __init debugfs_unaligned(
void)
560 if (!mips_debugfs_dir)
563 mips_debugfs_dir, &unaligned_instructions);