PageRenderTime 25ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/release/src/linux/linux/arch/mips64/kernel/unaligned.c

https://github.com/SgtPepperKSU/TomatoVPN
C | 553 lines | 357 code | 47 blank | 149 comment | 27 complexity | 87c612226ea1dbc9ba3f2c6ca1cb223d MD5 | raw file
  1. /*
  2. * Handle unaligned accesses by emulation.
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file "COPYING" in the main directory of this archive
  6. * for more details.
  7. *
  8. * Copyright (C) 1996, 1998, 1999, 2002 by Ralf Baechle
  9. * Copyright (C) 1999 Silicon Graphics, Inc.
  10. *
  11. * This file contains exception handler for address error exception with the
  12. * special capability to execute faulting instructions in software. The
  13. * handler does not try to handle the case when the program counter points
  14. * to an address not aligned to a word boundary.
  15. *
  16. * Putting data to unaligned addresses is a bad practice even on Intel where
  17. * only the performance is affected. Much worse is that such code is non-
  18. * portable. Due to several programs that die on MIPS due to alignment
  19. * problems I decided to implement this handler anyway though I originally
  20. * didn't intend to do this at all for user code.
  21. *
  22. * For now I enable fixing of address errors by default to make life easier.
  23. * I however intend to disable this somewhen in the future when the alignment
  24. * problems with user programs have been fixed. For programmers this is the
  25. * right way to go.
  26. *
  27. * Fixing address errors is a per process option. The option is inherited
  28. * across fork(2) and execve(2) calls. If you really want to use the
  29. * option in your user programs - I discourage the use of the software
  30. * emulation strongly - use the following code in your userland stuff:
  31. *
  32. * #include <sys/sysmips.h>
  33. *
  34. * ...
  35. * sysmips(MIPS_FIXADE, x);
  36. * ...
  37. *
  38. * The argument x is 0 for disabling software emulation, enabled otherwise.
  39. *
  40. * Below a little program to play around with this feature.
  41. *
  42. * #include <stdio.h>
  43. * #include <asm/sysmips.h>
  44. *
  45. * struct foo {
  46. * unsigned char bar[8];
  47. * };
  48. *
  49. * main(int argc, char *argv[])
  50. * {
  51. * struct foo x = {0, 1, 2, 3, 4, 5, 6, 7};
  52. * unsigned int *p = (unsigned int *) (x.bar + 3);
  53. * int i;
  54. *
  55. * if (argc > 1)
  56. * sysmips(MIPS_FIXADE, atoi(argv[1]));
  57. *
  58. * printf("*p = %08lx\n", *p);
  59. *
  60. * *p = 0xdeadface;
  61. *
  62. * for(i = 0; i <= 7; i++)
  63. * printf("%02x ", x.bar[i]);
  64. * printf("\n");
  65. * }
  66. *
  67. * Coprocessor loads are not supported; I think this case is unimportant
  68. * in the practice.
  69. *
  70. * TODO: Handle ndc (attempted store to doubleword in uncached memory)
  71. * exception for the R6000.
  72. * A store crossing a page boundary might be executed only partially.
  73. * Undo the partial store in this case.
  74. */
  75. #include <linux/config.h>
  76. #include <linux/mm.h>
  77. #include <linux/signal.h>
  78. #include <linux/smp.h>
  79. #include <linux/smp_lock.h>
  80. #include <asm/asm.h>
  81. #include <asm/branch.h>
  82. #include <asm/byteorder.h>
  83. #include <asm/inst.h>
  84. #include <asm/uaccess.h>
  85. #include <asm/system.h>
  86. #define STR(x) __STR(x)
  87. #define __STR(x) #x
  88. #ifdef CONFIG_PROC_FS
  89. unsigned long unaligned_instructions;
  90. #endif
  91. static inline int emulate_load_store_insn(struct pt_regs *regs,
  92. void *addr, unsigned long pc,
  93. unsigned long **regptr, unsigned long *newvalue)
  94. {
  95. union mips_instruction insn;
  96. unsigned long value, fixup;
  97. unsigned int res;
  98. regs->regs[0] = 0;
  99. *regptr=NULL;
  100. /*
  101. * This load never faults.
  102. */
  103. __get_user(insn.word, (unsigned int *)pc);
  104. switch (insn.i_format.opcode) {
  105. /*
  106. * These are instructions that a compiler doesn't generate. We
  107. * can assume therefore that the code is MIPS-aware and
  108. * really buggy. Emulating these instructions would break the
  109. * semantics anyway.
  110. */
  111. case ll_op:
  112. case lld_op:
  113. case sc_op:
  114. case scd_op:
  115. /*
  116. * For these instructions the only way to create an address
  117. * error is an attempted access to kernel/supervisor address
  118. * space.
  119. */
  120. case ldl_op:
  121. case ldr_op:
  122. case lwl_op:
  123. case lwr_op:
  124. case sdl_op:
  125. case sdr_op:
  126. case swl_op:
  127. case swr_op:
  128. case lb_op:
  129. case lbu_op:
  130. case sb_op:
  131. goto sigbus;
  132. /*
  133. * The remaining opcodes are the ones that are really of interest.
  134. */
  135. case lh_op:
  136. if (verify_area(VERIFY_READ, addr, 2))
  137. goto sigbus;
  138. __asm__(".set\tnoat\n"
  139. #ifdef __BIG_ENDIAN
  140. "1:\tlb\t%0, 0(%2)\n"
  141. "2:\tlbu\t$1, 1(%2)\n\t"
  142. #endif
  143. #ifdef __LITTLE_ENDIAN
  144. "1:\tlb\t%0, 1(%2)\n"
  145. "2:\tlbu\t$1, 0(%2)\n\t"
  146. #endif
  147. "sll\t%0, 0x8\n\t"
  148. "or\t%0, $1\n\t"
  149. "li\t%1, 0\n"
  150. "3:\t.set\tat\n\t"
  151. ".section\t.fixup,\"ax\"\n\t"
  152. "4:\tli\t%1, %3\n\t"
  153. "j\t3b\n\t"
  154. ".previous\n\t"
  155. ".section\t__ex_table,\"a\"\n\t"
  156. STR(PTR)"\t1b, 4b\n\t"
  157. STR(PTR)"\t2b, 4b\n\t"
  158. ".previous"
  159. : "=&r" (value), "=r" (res)
  160. : "r" (addr), "i" (-EFAULT));
  161. if (res)
  162. goto fault;
  163. *newvalue = value;
  164. *regptr = &regs->regs[insn.i_format.rt];
  165. break;
  166. case lw_op:
  167. if (verify_area(VERIFY_READ, addr, 4))
  168. goto sigbus;
  169. __asm__(
  170. #ifdef __BIG_ENDIAN
  171. "1:\tlwl\t%0, (%2)\n"
  172. "2:\tlwr\t%0, 3(%2)\n\t"
  173. #endif
  174. #ifdef __LITTLE_ENDIAN
  175. "1:\tlwl\t%0, 3(%2)\n"
  176. "2:\tlwr\t%0, (%2)\n\t"
  177. #endif
  178. "li\t%1, 0\n"
  179. "3:\t.section\t.fixup,\"ax\"\n\t"
  180. "4:\tli\t%1, %3\n\t"
  181. "j\t3b\n\t"
  182. ".previous\n\t"
  183. ".section\t__ex_table,\"a\"\n\t"
  184. STR(PTR)"\t1b, 4b\n\t"
  185. STR(PTR)"\t2b, 4b\n\t"
  186. ".previous"
  187. : "=&r" (value), "=r" (res)
  188. : "r" (addr), "i" (-EFAULT));
  189. if (res)
  190. goto fault;
  191. *newvalue = value;
  192. *regptr = &regs->regs[insn.i_format.rt];
  193. break;
  194. case lhu_op:
  195. if (verify_area(VERIFY_READ, addr, 2))
  196. goto sigbus;
  197. __asm__(
  198. ".set\tnoat\n"
  199. #ifdef __BIG_ENDIAN
  200. "1:\tlbu\t%0, 0(%2)\n"
  201. "2:\tlbu\t$1, 1(%2)\n\t"
  202. #endif
  203. #ifdef __LITTLE_ENDIAN
  204. "1:\tlbu\t%0, 1(%2)\n"
  205. "2:\tlbu\t$1, 0(%2)\n\t"
  206. #endif
  207. "sll\t%0, 0x8\n\t"
  208. "or\t%0, $1\n\t"
  209. "li\t%1, 0\n"
  210. "3:\t.set\tat\n\t"
  211. ".section\t.fixup,\"ax\"\n\t"
  212. "4:\tli\t%1, %3\n\t"
  213. "j\t3b\n\t"
  214. ".previous\n\t"
  215. ".section\t__ex_table,\"a\"\n\t"
  216. STR(PTR)"\t1b, 4b\n\t"
  217. STR(PTR)"\t2b, 4b\n\t"
  218. ".previous"
  219. : "=&r" (value), "=r" (res)
  220. : "r" (addr), "i" (-EFAULT));
  221. if (res)
  222. goto fault;
  223. *newvalue = value;
  224. *regptr = &regs->regs[insn.i_format.rt];
  225. break;
  226. case lwu_op:
  227. #ifdef CONFIG_MIPS64
  228. /*
  229. * A 32-bit kernel might be running on a 64-bit processor. But
  230. * if we're on a 32-bit processor and an i-cache incoherency
  231. * or race makes us see a 64-bit instruction here the sdl/sdr
  232. * would blow up, so for now we don't handle unaligned 64-bit
  233. * instructions on 32-bit kernels.
  234. */
  235. if (verify_area(VERIFY_READ, addr, 4))
  236. goto sigbus;
  237. __asm__(
  238. #ifdef __BIG_ENDIAN
  239. "1:\tlwl\t%0, (%2)\n"
  240. "2:\tlwr\t%0, 3(%2)\n\t"
  241. #endif
  242. #ifdef __LITTLE_ENDIAN
  243. "1:\tlwl\t%0, 3(%2)\n"
  244. "2:\tlwr\t%0, (%2)\n\t"
  245. #endif
  246. "dsll\t%0, %0, 32\n\t"
  247. "dsrl\t%0, %0, 32\n\t"
  248. "li\t%1, 0\n"
  249. "3:\t.section\t.fixup,\"ax\"\n\t"
  250. "4:\tli\t%1, %3\n\t"
  251. "j\t3b\n\t"
  252. ".previous\n\t"
  253. ".section\t__ex_table,\"a\"\n\t"
  254. STR(PTR)"\t1b, 4b\n\t"
  255. STR(PTR)"\t2b, 4b\n\t"
  256. ".previous"
  257. : "=&r" (value), "=r" (res)
  258. : "r" (addr), "i" (-EFAULT));
  259. if (res)
  260. goto fault;
  261. *newvalue = value;
  262. *regptr = &regs->regs[insn.i_format.rt];
  263. break;
  264. #endif /* CONFIG_MIPS64 */
  265. /* Cannot handle 64-bit instructions in 32-bit kernel */
  266. goto sigill;
  267. case ld_op:
  268. #ifdef CONFIG_MIPS64
  269. /*
  270. * A 32-bit kernel might be running on a 64-bit processor. But
  271. * if we're on a 32-bit processor and an i-cache incoherency
  272. * or race makes us see a 64-bit instruction here the sdl/sdr
  273. * would blow up, so for now we don't handle unaligned 64-bit
  274. * instructions on 32-bit kernels.
  275. */
  276. if (verify_area(VERIFY_READ, addr, 8))
  277. goto sigbus;
  278. __asm__(
  279. #ifdef __BIG_ENDIAN
  280. "1:\tldl\t%0, (%2)\n"
  281. "2:\tldr\t%0, 7(%2)\n\t"
  282. #endif
  283. #ifdef __LITTLE_ENDIAN
  284. "1:\tldl\t%0, 7(%2)\n"
  285. "2:\tldr\t%0, (%2)\n\t"
  286. #endif
  287. "li\t%1, 0\n"
  288. "3:\t.section\t.fixup,\"ax\"\n\t"
  289. "4:\tli\t%1, %3\n\t"
  290. "j\t3b\n\t"
  291. ".previous\n\t"
  292. ".section\t__ex_table,\"a\"\n\t"
  293. STR(PTR)"\t1b, 4b\n\t"
  294. STR(PTR)"\t2b, 4b\n\t"
  295. ".previous"
  296. : "=&r" (value), "=r" (res)
  297. : "r" (addr), "i" (-EFAULT));
  298. if (res)
  299. goto fault;
  300. *newvalue = value;
  301. *regptr = &regs->regs[insn.i_format.rt];
  302. break;
  303. #endif /* CONFIG_MIPS64 */
  304. /* Cannot handle 64-bit instructions in 32-bit kernel */
  305. goto sigill;
  306. case sh_op:
  307. if (verify_area(VERIFY_WRITE, addr, 2))
  308. goto sigbus;
  309. value = regs->regs[insn.i_format.rt];
  310. __asm__(
  311. #ifdef __BIG_ENDIAN
  312. ".set\tnoat\n"
  313. "1:\tsb\t%1, 1(%2)\n\t"
  314. "srl\t$1, %1, 0x8\n"
  315. "2:\tsb\t$1, 0(%2)\n\t"
  316. ".set\tat\n\t"
  317. #endif
  318. #ifdef __LITTLE_ENDIAN
  319. ".set\tnoat\n"
  320. "1:\tsb\t%1, 0(%2)\n\t"
  321. "srl\t$1,%1, 0x8\n"
  322. "2:\tsb\t$1, 1(%2)\n\t"
  323. ".set\tat\n\t"
  324. #endif
  325. "li\t%0, 0\n"
  326. "3:\n\t"
  327. ".section\t.fixup,\"ax\"\n\t"
  328. "4:\tli\t%0, %3\n\t"
  329. "j\t3b\n\t"
  330. ".previous\n\t"
  331. ".section\t__ex_table,\"a\"\n\t"
  332. STR(PTR)"\t1b, 4b\n\t"
  333. STR(PTR)"\t2b, 4b\n\t"
  334. ".previous"
  335. : "=r" (res)
  336. : "r" (value), "r" (addr), "i" (-EFAULT));
  337. if (res)
  338. goto fault;
  339. break;
  340. case sw_op:
  341. if (verify_area(VERIFY_WRITE, addr, 4))
  342. goto sigbus;
  343. value = regs->regs[insn.i_format.rt];
  344. __asm__(
  345. #ifdef __BIG_ENDIAN
  346. "1:\tswl\t%1,(%2)\n"
  347. "2:\tswr\t%1, 3(%2)\n\t"
  348. #endif
  349. #ifdef __LITTLE_ENDIAN
  350. "1:\tswl\t%1, 3(%2)\n"
  351. "2:\tswr\t%1, (%2)\n\t"
  352. #endif
  353. "li\t%0, 0\n"
  354. "3:\n\t"
  355. ".section\t.fixup,\"ax\"\n\t"
  356. "4:\tli\t%0, %3\n\t"
  357. "j\t3b\n\t"
  358. ".previous\n\t"
  359. ".section\t__ex_table,\"a\"\n\t"
  360. STR(PTR)"\t1b, 4b\n\t"
  361. STR(PTR)"\t2b, 4b\n\t"
  362. ".previous"
  363. : "=r" (res)
  364. : "r" (value), "r" (addr), "i" (-EFAULT));
  365. if (res)
  366. goto fault;
  367. break;
  368. case sd_op:
  369. #ifdef CONFIG_MIPS64
  370. /*
  371. * A 32-bit kernel might be running on a 64-bit processor. But
  372. * if we're on a 32-bit processor and an i-cache incoherency
  373. * or race makes us see a 64-bit instruction here the sdl/sdr
  374. * would blow up, so for now we don't handle unaligned 64-bit
  375. * instructions on 32-bit kernels.
  376. */
  377. if (verify_area(VERIFY_WRITE, addr, 8))
  378. goto sigbus;
  379. value = regs->regs[insn.i_format.rt];
  380. __asm__(
  381. #ifdef __BIG_ENDIAN
  382. "1:\tsdl\t%1,(%2)\n"
  383. "2:\tsdr\t%1, 7(%2)\n\t"
  384. #endif
  385. #ifdef __LITTLE_ENDIAN
  386. "1:\tsdl\t%1, 7(%2)\n"
  387. "2:\tsdr\t%1, (%2)\n\t"
  388. #endif
  389. "li\t%0, 0\n"
  390. "3:\n\t"
  391. ".section\t.fixup,\"ax\"\n\t"
  392. "4:\tli\t%0, %3\n\t"
  393. "j\t3b\n\t"
  394. ".previous\n\t"
  395. ".section\t__ex_table,\"a\"\n\t"
  396. STR(PTR)"\t1b, 4b\n\t"
  397. STR(PTR)"\t2b, 4b\n\t"
  398. ".previous"
  399. : "=r" (res)
  400. : "r" (value), "r" (addr), "i" (-EFAULT));
  401. if (res)
  402. goto fault;
  403. break;
  404. #endif /* CONFIG_MIPS64 */
  405. /* Cannot handle 64-bit instructions in 32-bit kernel */
  406. goto sigill;
  407. case lwc1_op:
  408. case ldc1_op:
  409. case swc1_op:
  410. case sdc1_op:
  411. /*
  412. * I herewith declare: this does not happen. So send SIGBUS.
  413. */
  414. goto sigbus;
  415. case lwc2_op:
  416. case ldc2_op:
  417. case swc2_op:
  418. case sdc2_op:
  419. /*
  420. * These are the coprocessor 2 load/stores. The current
  421. * implementations don't use cp2 and cp2 should always be
  422. * disabled in c0_status. So send SIGILL.
  423. * (No longer true: The Sony Praystation uses cp2 for
  424. * 3D matrix operations. Dunno if that thingy has a MMU ...)
  425. */
  426. default:
  427. /*
  428. * Pheeee... We encountered an yet unknown instruction or
  429. * cache coherence problem. Die sucker, die ...
  430. */
  431. goto sigill;
  432. }
  433. #ifdef CONFIG_PROC_FS
  434. unaligned_instructions++;
  435. #endif
  436. return 0;
  437. fault:
  438. /* Did we have an exception handler installed? */
  439. fixup = search_exception_table(exception_epc(regs));
  440. if (fixup) {
  441. long new_epc;
  442. new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
  443. printk(KERN_DEBUG "%s: Forwarding exception at [<%lx>] (%lx)\n",
  444. current->comm, regs->cp0_epc, new_epc);
  445. regs->cp0_epc = new_epc;
  446. return 1;
  447. }
  448. die_if_kernel ("Unhandled kernel unaligned access", regs);
  449. send_sig(SIGSEGV, current, 1);
  450. return 0;
  451. sigbus:
  452. die_if_kernel("Unhandled kernel unaligned access", regs);
  453. send_sig(SIGBUS, current, 1);
  454. return 0;
  455. sigill:
  456. die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs);
  457. send_sig(SIGILL, current, 1);
  458. return 0;
  459. }
  460. asmlinkage void do_ade(struct pt_regs *regs)
  461. {
  462. unsigned long *regptr, newval;
  463. extern int do_dsemulret(struct pt_regs *);
  464. mm_segment_t seg;
  465. unsigned long pc;
  466. /*
  467. * Address errors may be deliberately induced by the FPU emulator to
  468. * take retake control of the CPU after executing the instruction in
  469. * the delay slot of an emulated branch.
  470. */
  471. /* Terminate if exception was recognized as a delay slot return */
  472. if (do_dsemulret(regs))
  473. return;
  474. /* Otherwise handle as normal */
  475. /*
  476. * Did we catch a fault trying to load an instruction?
  477. * Or are we running in MIPS16 mode?
  478. */
  479. if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1))
  480. goto sigbus;
  481. pc = exception_epc(regs);
  482. if ((current->thread.mflags & MF_FIXADE) == 0)
  483. goto sigbus;
  484. /*
  485. * Do branch emulation only if we didn't forward the exception.
  486. * This is all so but ugly ...
  487. */
  488. seg = get_fs();
  489. if (!user_mode(regs))
  490. set_fs(KERNEL_DS);
  491. if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc,
  492. &regptr, &newval)) {
  493. compute_return_epc(regs);
  494. /*
  495. * Now that branch is evaluated, update the dest
  496. * register if necessary
  497. */
  498. if (regptr)
  499. *regptr = newval;
  500. }
  501. set_fs(seg);
  502. return;
  503. sigbus:
  504. die_if_kernel("Kernel unaligned instruction access", regs);
  505. force_sig(SIGBUS, current);
  506. }