uaccess.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. #ifndef __M68K_UACCESS_H
  2. #define __M68K_UACCESS_H
  3. /*
  4. * User space memory access functions
  5. */
  6. #include <linux/errno.h>
  7. #include <linux/sched.h>
  8. #include <asm/segment.h>
  9. #define VERIFY_READ 0
  10. #define VERIFY_WRITE 1
  11. /* We let the MMU do all checking */
  12. #define access_ok(type,addr,size) 1
  13. /*
  14. * The exception table consists of pairs of addresses: the first is the
  15. * address of an instruction that is allowed to fault, and the second is
  16. * the address at which the program should continue. No registers are
  17. * modified, so it is entirely up to the continuation code to figure out
  18. * what to do.
  19. *
  20. * All the routines below use bits of fixup code that are out of line
  21. * with the main instruction path. This means when everything is well,
  22. * we don't even have to jump over them. Further, they do not intrude
  23. * on our cache or tlb entries.
  24. */
  25. struct exception_table_entry
  26. {
  27. unsigned long insn, fixup;
  28. };
  29. /*
  30. * These are the main single-value transfer routines. They automatically
  31. * use the right size if we just have the right pointer type.
  32. */
  33. #define put_user(x, ptr) \
  34. ({ \
  35. int __pu_err; \
  36. typeof(*(ptr)) __pu_val = (x); \
  37. switch (sizeof (*(ptr))) { \
  38. case 1: \
  39. __put_user_asm(__pu_err, __pu_val, ptr, b); \
  40. break; \
  41. case 2: \
  42. __put_user_asm(__pu_err, __pu_val, ptr, w); \
  43. break; \
  44. case 4: \
  45. __put_user_asm(__pu_err, __pu_val, ptr, l); \
  46. break; \
  47. case 8: \
  48. __pu_err = __constant_copy_to_user(ptr, &__pu_val, 8); \
  49. break; \
  50. default: \
  51. __pu_err = __put_user_bad(); \
  52. break; \
  53. } \
  54. __pu_err; \
  55. })
  56. #define __put_user(x, ptr) put_user(x, ptr)
  57. extern int __put_user_bad(void);
  58. /*
  59. * Tell gcc we read from memory instead of writing: this is because
  60. * we do not write to any memory gcc knows about, so there are no
  61. * aliasing issues.
  62. */
  63. #define __put_user_asm(err,x,ptr,bwl) \
  64. __asm__ __volatile__ \
  65. ("21:moves" #bwl " %2,%1\n" \
  66. "1:\n" \
  67. ".section .fixup,\"ax\"\n" \
  68. " .even\n" \
  69. "2: movel %3,%0\n" \
  70. " jra 1b\n" \
  71. ".previous\n" \
  72. ".section __ex_table,\"a\"\n" \
  73. " .align 4\n" \
  74. " .long 21b,2b\n" \
  75. " .long 1b,2b\n" \
  76. ".previous" \
  77. : "=d"(err) \
  78. : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
  79. #define get_user(x, ptr) \
  80. ({ \
  81. int __gu_err; \
  82. typeof(*(ptr)) __gu_val; \
  83. switch (sizeof(*(ptr))) { \
  84. case 1: \
  85. __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \
  86. break; \
  87. case 2: \
  88. __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \
  89. break; \
  90. case 4: \
  91. __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \
  92. break; \
  93. case 8: \
  94. __gu_err = __constant_copy_from_user(&__gu_val, ptr, 8); \
  95. break; \
  96. default: \
  97. __gu_val = 0; \
  98. __gu_err = __get_user_bad(); \
  99. break; \
  100. } \
  101. (x) = __gu_val; \
  102. __gu_err; \
  103. })
  104. #define __get_user(x, ptr) get_user(x, ptr)
  105. extern int __get_user_bad(void);
  106. #define __get_user_asm(err,x,ptr,bwl,reg) \
  107. __asm__ __volatile__ \
  108. ("1: moves" #bwl " %2,%1\n" \
  109. "2:\n" \
  110. ".section .fixup,\"ax\"\n" \
  111. " .even\n" \
  112. "3: movel %3,%0\n" \
  113. " sub" #bwl " %1,%1\n" \
  114. " jra 2b\n" \
  115. ".previous\n" \
  116. ".section __ex_table,\"a\"\n" \
  117. " .align 4\n" \
  118. " .long 1b,3b\n" \
  119. ".previous" \
  120. : "=d"(err), reg(x) \
  121. : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
  122. static inline unsigned long
  123. __generic_copy_from_user(void *to, const void *from, unsigned long n)
  124. {
  125. unsigned long tmp;
  126. __asm__ __volatile__
  127. (" tstl %2\n"
  128. " jeq 2f\n"
  129. "1: movesl (%1)+,%3\n"
  130. " movel %3,(%0)+\n"
  131. " subql #1,%2\n"
  132. " jne 1b\n"
  133. "2: movel %4,%2\n"
  134. " bclr #1,%2\n"
  135. " jeq 4f\n"
  136. "3: movesw (%1)+,%3\n"
  137. " movew %3,(%0)+\n"
  138. "4: bclr #0,%2\n"
  139. " jeq 6f\n"
  140. "5: movesb (%1)+,%3\n"
  141. " moveb %3,(%0)+\n"
  142. "6:\n"
  143. ".section .fixup,\"ax\"\n"
  144. " .even\n"
  145. "7: movel %2,%%d0\n"
  146. "71:clrl (%0)+\n"
  147. " subql #1,%%d0\n"
  148. " jne 71b\n"
  149. " lsll #2,%2\n"
  150. " addl %4,%2\n"
  151. " btst #1,%4\n"
  152. " jne 81f\n"
  153. " btst #0,%4\n"
  154. " jne 91f\n"
  155. " jra 6b\n"
  156. "8: addql #2,%2\n"
  157. "81:clrw (%0)+\n"
  158. " btst #0,%4\n"
  159. " jne 91f\n"
  160. " jra 6b\n"
  161. "9: addql #1,%2\n"
  162. "91:clrb (%0)+\n"
  163. " jra 6b\n"
  164. ".previous\n"
  165. ".section __ex_table,\"a\"\n"
  166. " .align 4\n"
  167. " .long 1b,7b\n"
  168. " .long 3b,8b\n"
  169. " .long 5b,9b\n"
  170. ".previous"
  171. : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
  172. : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
  173. : "d0", "memory");
  174. return n;
  175. }
  176. static inline unsigned long
  177. __generic_copy_to_user(void *to, const void *from, unsigned long n)
  178. {
  179. unsigned long tmp;
  180. __asm__ __volatile__
  181. (" tstl %2\n"
  182. " jeq 3f\n"
  183. "1: movel (%1)+,%3\n"
  184. "22:movesl %3,(%0)+\n"
  185. "2: subql #1,%2\n"
  186. " jne 1b\n"
  187. "3: movel %4,%2\n"
  188. " bclr #1,%2\n"
  189. " jeq 4f\n"
  190. " movew (%1)+,%3\n"
  191. "24:movesw %3,(%0)+\n"
  192. "4: bclr #0,%2\n"
  193. " jeq 5f\n"
  194. " moveb (%1)+,%3\n"
  195. "25:movesb %3,(%0)+\n"
  196. "5:\n"
  197. ".section .fixup,\"ax\"\n"
  198. " .even\n"
  199. "60:addql #1,%2\n"
  200. "6: lsll #2,%2\n"
  201. " addl %4,%2\n"
  202. " jra 5b\n"
  203. "7: addql #2,%2\n"
  204. " jra 5b\n"
  205. "8: addql #1,%2\n"
  206. " jra 5b\n"
  207. ".previous\n"
  208. ".section __ex_table,\"a\"\n"
  209. " .align 4\n"
  210. " .long 1b,60b\n"
  211. " .long 22b,6b\n"
  212. " .long 2b,6b\n"
  213. " .long 24b,7b\n"
  214. " .long 3b,60b\n"
  215. " .long 4b,7b\n"
  216. " .long 25b,8b\n"
  217. " .long 5b,8b\n"
  218. ".previous"
  219. : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
  220. : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
  221. : "memory");
  222. return n;
  223. }
  224. #define __copy_from_user_big(to, from, n, fixup, copy) \
  225. __asm__ __volatile__ \
  226. ("10: movesl (%1)+,%%d0\n" \
  227. " movel %%d0,(%0)+\n" \
  228. " subql #1,%2\n" \
  229. " jne 10b\n" \
  230. ".section .fixup,\"ax\"\n" \
  231. " .even\n" \
  232. "11: movel %2,%%d0\n" \
  233. "13: clrl (%0)+\n" \
  234. " subql #1,%%d0\n" \
  235. " jne 13b\n" \
  236. " lsll #2,%2\n" \
  237. fixup "\n" \
  238. " jra 12f\n" \
  239. ".previous\n" \
  240. ".section __ex_table,\"a\"\n" \
  241. " .align 4\n" \
  242. " .long 10b,11b\n" \
  243. ".previous\n" \
  244. copy "\n" \
  245. "12:" \
  246. : "=a"(to), "=a"(from), "=d"(n) \
  247. : "0"(to), "1"(from), "2"(n/4) \
  248. : "d0", "memory")
  249. static inline unsigned long
  250. __constant_copy_from_user(void *to, const void *from, unsigned long n)
  251. {
  252. switch (n) {
  253. case 0:
  254. break;
  255. case 1:
  256. __asm__ __volatile__
  257. ("1: movesb (%1)+,%%d0\n"
  258. " moveb %%d0,(%0)+\n"
  259. "2:\n"
  260. ".section .fixup,\"ax\"\n"
  261. " .even\n"
  262. "3: addql #1,%2\n"
  263. " clrb (%0)+\n"
  264. " jra 2b\n"
  265. ".previous\n"
  266. ".section __ex_table,\"a\"\n"
  267. " .align 4\n"
  268. " .long 1b,3b\n"
  269. ".previous"
  270. : "=a"(to), "=a"(from), "=d"(n)
  271. : "0"(to), "1"(from), "2"(0)
  272. : "d0", "memory");
  273. break;
  274. case 2:
  275. __asm__ __volatile__
  276. ("1: movesw (%1)+,%%d0\n"
  277. " movew %%d0,(%0)+\n"
  278. "2:\n"
  279. ".section .fixup,\"ax\"\n"
  280. " .even\n"
  281. "3: addql #2,%2\n"
  282. " clrw (%0)+\n"
  283. " jra 2b\n"
  284. ".previous\n"
  285. ".section __ex_table,\"a\"\n"
  286. " .align 4\n"
  287. " .long 1b,3b\n"
  288. ".previous"
  289. : "=a"(to), "=a"(from), "=d"(n)
  290. : "0"(to), "1"(from), "2"(0)
  291. : "d0", "memory");
  292. break;
  293. case 3:
  294. __asm__ __volatile__
  295. ("1: movesw (%1)+,%%d0\n"
  296. " movew %%d0,(%0)+\n"
  297. "2: movesb (%1)+,%%d0\n"
  298. " moveb %%d0,(%0)+\n"
  299. "3:"
  300. ".section .fixup,\"ax\"\n"
  301. " .even\n"
  302. "4: addql #2,%2\n"
  303. " clrw (%0)+\n"
  304. "5: addql #1,%2\n"
  305. " clrb (%0)+\n"
  306. " jra 3b\n"
  307. ".previous\n"
  308. ".section __ex_table,\"a\"\n"
  309. " .align 4\n"
  310. " .long 1b,4b\n"
  311. " .long 2b,5b\n"
  312. ".previous"
  313. : "=a"(to), "=a"(from), "=d"(n)
  314. : "0"(to), "1"(from), "2"(0)
  315. : "d0", "memory");
  316. break;
  317. case 4:
  318. __asm__ __volatile__
  319. ("1: movesl (%1)+,%%d0\n"
  320. " movel %%d0,(%0)+\n"
  321. "2:"
  322. ".section .fixup,\"ax\"\n"
  323. " .even\n"
  324. "3: addql #4,%2\n"
  325. " clrl (%0)+\n"
  326. " jra 2b\n"
  327. ".previous\n"
  328. ".section __ex_table,\"a\"\n"
  329. " .align 4\n"
  330. " .long 1b,3b\n"
  331. ".previous"
  332. : "=a"(to), "=a"(from), "=d"(n)
  333. : "0"(to), "1"(from), "2"(0)
  334. : "d0", "memory");
  335. break;
  336. case 8:
  337. __asm__ __volatile__
  338. ("1: movesl (%1)+,%%d0\n"
  339. " movel %%d0,(%0)+\n"
  340. "2: movesl (%1)+,%%d0\n"
  341. " movel %%d0,(%0)+\n"
  342. "3:"
  343. ".section .fixup,\"ax\"\n"
  344. " .even\n"
  345. "4: addql #4,%2\n"
  346. " clrl (%0)+\n"
  347. "5: addql #4,%2\n"
  348. " clrl (%0)+\n"
  349. " jra 3b\n"
  350. ".previous\n"
  351. ".section __ex_table,\"a\"\n"
  352. " .align 4\n"
  353. " .long 1b,4b\n"
  354. " .long 2b,5b\n"
  355. ".previous"
  356. : "=a"(to), "=a"(from), "=d"(n)
  357. : "0"(to), "1"(from), "2"(0)
  358. : "d0", "memory");
  359. break;
  360. case 12:
  361. __asm__ __volatile__
  362. ("1: movesl (%1)+,%%d0\n"
  363. " movel %%d0,(%0)+\n"
  364. "2: movesl (%1)+,%%d0\n"
  365. " movel %%d0,(%0)+\n"
  366. "3: movesl (%1)+,%%d0\n"
  367. " movel %%d0,(%0)+\n"
  368. "4:"
  369. ".section .fixup,\"ax\"\n"
  370. " .even\n"
  371. "5: addql #4,%2\n"
  372. " clrl (%0)+\n"
  373. "6: addql #4,%2\n"
  374. " clrl (%0)+\n"
  375. "7: addql #4,%2\n"
  376. " clrl (%0)+\n"
  377. " jra 4b\n"
  378. ".previous\n"
  379. ".section __ex_table,\"a\"\n"
  380. " .align 4\n"
  381. " .long 1b,5b\n"
  382. " .long 2b,6b\n"
  383. " .long 3b,7b\n"
  384. ".previous"
  385. : "=a"(to), "=a"(from), "=d"(n)
  386. : "0"(to), "1"(from), "2"(0)
  387. : "d0", "memory");
  388. break;
  389. case 16:
  390. __asm__ __volatile__
  391. ("1: movesl (%1)+,%%d0\n"
  392. " movel %%d0,(%0)+\n"
  393. "2: movesl (%1)+,%%d0\n"
  394. " movel %%d0,(%0)+\n"
  395. "3: movesl (%1)+,%%d0\n"
  396. " movel %%d0,(%0)+\n"
  397. "4: movesl (%1)+,%%d0\n"
  398. " movel %%d0,(%0)+\n"
  399. "5:"
  400. ".section .fixup,\"ax\"\n"
  401. " .even\n"
  402. "6: addql #4,%2\n"
  403. " clrl (%0)+\n"
  404. "7: addql #4,%2\n"
  405. " clrl (%0)+\n"
  406. "8: addql #4,%2\n"
  407. " clrl (%0)+\n"
  408. "9: addql #4,%2\n"
  409. " clrl (%0)+\n"
  410. " jra 5b\n"
  411. ".previous\n"
  412. ".section __ex_table,\"a\"\n"
  413. " .align 4\n"
  414. " .long 1b,6b\n"
  415. " .long 2b,7b\n"
  416. " .long 3b,8b\n"
  417. " .long 4b,9b\n"
  418. ".previous"
  419. : "=a"(to), "=a"(from), "=d"(n)
  420. : "0"(to), "1"(from), "2"(0)
  421. : "d0", "memory");
  422. break;
  423. default:
  424. switch (n & 3) {
  425. case 0:
  426. __copy_from_user_big(to, from, n, "", "");
  427. break;
  428. case 1:
  429. __copy_from_user_big(to, from, n,
  430. /* fixup */
  431. "1: addql #1,%2\n"
  432. " clrb (%0)+",
  433. /* copy */
  434. "2: movesb (%1)+,%%d0\n"
  435. " moveb %%d0,(%0)+\n"
  436. ".section __ex_table,\"a\"\n"
  437. " .long 2b,1b\n"
  438. ".previous");
  439. break;
  440. case 2:
  441. __copy_from_user_big(to, from, n,
  442. /* fixup */
  443. "1: addql #2,%2\n"
  444. " clrw (%0)+",
  445. /* copy */
  446. "2: movesw (%1)+,%%d0\n"
  447. " movew %%d0,(%0)+\n"
  448. ".section __ex_table,\"a\"\n"
  449. " .long 2b,1b\n"
  450. ".previous");
  451. break;
  452. case 3:
  453. __copy_from_user_big(to, from, n,
  454. /* fixup */
  455. "1: addql #2,%2\n"
  456. " clrw (%0)+\n"
  457. "2: addql #1,%2\n"
  458. " clrb (%0)+",
  459. /* copy */
  460. "3: movesw (%1)+,%%d0\n"
  461. " movew %%d0,(%0)+\n"
  462. "4: movesb (%1)+,%%d0\n"
  463. " moveb %%d0,(%0)+\n"
  464. ".section __ex_table,\"a\"\n"
  465. " .long 3b,1b\n"
  466. " .long 4b,2b\n"
  467. ".previous");
  468. break;
  469. }
  470. break;
  471. }
  472. return n;
  473. }
  474. #define __copy_to_user_big(to, from, n, fixup, copy) \
  475. __asm__ __volatile__ \
  476. ("10: movel (%1)+,%%d0\n" \
  477. "31: movesl %%d0,(%0)+\n" \
  478. "11: subql #1,%2\n" \
  479. " jne 10b\n" \
  480. "41:\n" \
  481. ".section .fixup,\"ax\"\n" \
  482. " .even\n" \
  483. "22: addql #1,%2\n" \
  484. "12: lsll #2,%2\n" \
  485. fixup "\n" \
  486. " jra 13f\n" \
  487. ".previous\n" \
  488. ".section __ex_table,\"a\"\n" \
  489. " .align 4\n" \
  490. " .long 10b,22b\n" \
  491. " .long 31b,12b\n" \
  492. " .long 11b,12b\n" \
  493. " .long 41b,22b\n" \
  494. ".previous\n" \
  495. copy "\n" \
  496. "13:" \
  497. : "=a"(to), "=a"(from), "=d"(n) \
  498. : "0"(to), "1"(from), "2"(n/4) \
  499. : "d0", "memory")
  500. #define __copy_to_user_inatomic __copy_to_user
  501. #define __copy_from_user_inatomic __copy_from_user
  502. static inline unsigned long
  503. __constant_copy_to_user(void *to, const void *from, unsigned long n)
  504. {
  505. switch (n) {
  506. case 0:
  507. break;
  508. case 1:
  509. __asm__ __volatile__
  510. (" moveb (%1)+,%%d0\n"
  511. "21:movesb %%d0,(%0)+\n"
  512. "1:\n"
  513. ".section .fixup,\"ax\"\n"
  514. " .even\n"
  515. "2: addql #1,%2\n"
  516. " jra 1b\n"
  517. ".previous\n"
  518. ".section __ex_table,\"a\"\n"
  519. " .align 4\n "
  520. " .long 21b,2b\n"
  521. " .long 1b,2b\n"
  522. ".previous"
  523. : "=a"(to), "=a"(from), "=d"(n)
  524. : "0"(to), "1"(from), "2"(0)
  525. : "d0", "memory");
  526. break;
  527. case 2:
  528. __asm__ __volatile__
  529. (" movew (%1)+,%%d0\n"
  530. "21:movesw %%d0,(%0)+\n"
  531. "1:\n"
  532. ".section .fixup,\"ax\"\n"
  533. " .even\n"
  534. "2: addql #2,%2\n"
  535. " jra 1b\n"
  536. ".previous\n"
  537. ".section __ex_table,\"a\"\n"
  538. " .align 4\n"
  539. " .long 21b,2b\n"
  540. " .long 1b,2b\n"
  541. ".previous"
  542. : "=a"(to), "=a"(from), "=d"(n)
  543. : "0"(to), "1"(from), "2"(0)
  544. : "d0", "memory");
  545. break;
  546. case 3:
  547. __asm__ __volatile__
  548. (" movew (%1)+,%%d0\n"
  549. "21:movesw %%d0,(%0)+\n"
  550. "1: moveb (%1)+,%%d0\n"
  551. "22:movesb %%d0,(%0)+\n"
  552. "2:\n"
  553. ".section .fixup,\"ax\"\n"
  554. " .even\n"
  555. "3: addql #2,%2\n"
  556. "4: addql #1,%2\n"
  557. " jra 2b\n"
  558. ".previous\n"
  559. ".section __ex_table,\"a\"\n"
  560. " .align 4\n"
  561. " .long 21b,3b\n"
  562. " .long 1b,3b\n"
  563. " .long 22b,4b\n"
  564. " .long 2b,4b\n"
  565. ".previous"
  566. : "=a"(to), "=a"(from), "=d"(n)
  567. : "0"(to), "1"(from), "2"(0)
  568. : "d0", "memory");
  569. break;
  570. case 4:
  571. __asm__ __volatile__
  572. (" movel (%1)+,%%d0\n"
  573. "21:movesl %%d0,(%0)+\n"
  574. "1:\n"
  575. ".section .fixup,\"ax\"\n"
  576. " .even\n"
  577. "2: addql #4,%2\n"
  578. " jra 1b\n"
  579. ".previous\n"
  580. ".section __ex_table,\"a\"\n"
  581. " .align 4\n"
  582. " .long 21b,2b\n"
  583. " .long 1b,2b\n"
  584. ".previous"
  585. : "=a"(to), "=a"(from), "=d"(n)
  586. : "0"(to), "1"(from), "2"(0)
  587. : "d0", "memory");
  588. break;
  589. case 8:
  590. __asm__ __volatile__
  591. (" movel (%1)+,%%d0\n"
  592. "21:movesl %%d0,(%0)+\n"
  593. "1: movel (%1)+,%%d0\n"
  594. "22:movesl %%d0,(%0)+\n"
  595. "2:\n"
  596. ".section .fixup,\"ax\"\n"
  597. " .even\n"
  598. "3: addql #4,%2\n"
  599. "4: addql #4,%2\n"
  600. " jra 2b\n"
  601. ".previous\n"
  602. ".section __ex_table,\"a\"\n"
  603. " .align 4\n"
  604. " .long 21b,3b\n"
  605. " .long 1b,3b\n"
  606. " .long 22b,4b\n"
  607. " .long 2b,4b\n"
  608. ".previous"
  609. : "=a"(to), "=a"(from), "=d"(n)
  610. : "0"(to), "1"(from), "2"(0)
  611. : "d0", "memory");
  612. break;
  613. case 12:
  614. __asm__ __volatile__
  615. (" movel (%1)+,%%d0\n"
  616. "21:movesl %%d0,(%0)+\n"
  617. "1: movel (%1)+,%%d0\n"
  618. "22:movesl %%d0,(%0)+\n"
  619. "2: movel (%1)+,%%d0\n"
  620. "23:movesl %%d0,(%0)+\n"
  621. "3:\n"
  622. ".section .fixup,\"ax\"\n"
  623. " .even\n"
  624. "4: addql #4,%2\n"
  625. "5: addql #4,%2\n"
  626. "6: addql #4,%2\n"
  627. " jra 3b\n"
  628. ".previous\n"
  629. ".section __ex_table,\"a\"\n"
  630. " .align 4\n"
  631. " .long 21b,4b\n"
  632. " .long 1b,4b\n"
  633. " .long 22b,5b\n"
  634. " .long 2b,5b\n"
  635. " .long 23b,6b\n"
  636. " .long 3b,6b\n"
  637. ".previous"
  638. : "=a"(to), "=a"(from), "=d"(n)
  639. : "0"(to), "1"(from), "2"(0)
  640. : "d0", "memory");
  641. break;
  642. case 16:
  643. __asm__ __volatile__
  644. (" movel (%1)+,%%d0\n"
  645. "21:movesl %%d0,(%0)+\n"
  646. "1: movel (%1)+,%%d0\n"
  647. "22:movesl %%d0,(%0)+\n"
  648. "2: movel (%1)+,%%d0\n"
  649. "23:movesl %%d0,(%0)+\n"
  650. "3: movel (%1)+,%%d0\n"
  651. "24:movesl %%d0,(%0)+\n"
  652. "4:"
  653. ".section .fixup,\"ax\"\n"
  654. " .even\n"
  655. "5: addql #4,%2\n"
  656. "6: addql #4,%2\n"
  657. "7: addql #4,%2\n"
  658. "8: addql #4,%2\n"
  659. " jra 4b\n"
  660. ".previous\n"
  661. ".section __ex_table,\"a\"\n"
  662. " .align 4\n"
  663. " .long 21b,5b\n"
  664. " .long 1b,5b\n"
  665. " .long 22b,6b\n"
  666. " .long 2b,6b\n"
  667. " .long 23b,7b\n"
  668. " .long 3b,7b\n"
  669. " .long 24b,8b\n"
  670. " .long 4b,8b\n"
  671. ".previous"
  672. : "=a"(to), "=a"(from), "=d"(n)
  673. : "0"(to), "1"(from), "2"(0)
  674. : "d0", "memory");
  675. break;
  676. default:
  677. switch (n & 3) {
  678. case 0:
  679. __copy_to_user_big(to, from, n, "", "");
  680. break;
  681. case 1:
  682. __copy_to_user_big(to, from, n,
  683. /* fixup */
  684. "1: addql #1,%2",
  685. /* copy */
  686. " moveb (%1)+,%%d0\n"
  687. "22:movesb %%d0,(%0)+\n"
  688. "2:"
  689. ".section __ex_table,\"a\"\n"
  690. " .long 22b,1b\n"
  691. " .long 2b,1b\n"
  692. ".previous");
  693. break;
  694. case 2:
  695. __copy_to_user_big(to, from, n,
  696. /* fixup */
  697. "1: addql #2,%2",
  698. /* copy */
  699. " movew (%1)+,%%d0\n"
  700. "22:movesw %%d0,(%0)+\n"
  701. "2:"
  702. ".section __ex_table,\"a\"\n"
  703. " .long 22b,1b\n"
  704. " .long 2b,1b\n"
  705. ".previous");
  706. break;
  707. case 3:
  708. __copy_to_user_big(to, from, n,
  709. /* fixup */
  710. "1: addql #2,%2\n"
  711. "2: addql #1,%2",
  712. /* copy */
  713. " movew (%1)+,%%d0\n"
  714. "23:movesw %%d0,(%0)+\n"
  715. "3: moveb (%1)+,%%d0\n"
  716. "24:movesb %%d0,(%0)+\n"
  717. "4:"
  718. ".section __ex_table,\"a\"\n"
  719. " .long 23b,1b\n"
  720. " .long 3b,1b\n"
  721. " .long 24b,2b\n"
  722. " .long 4b,2b\n"
  723. ".previous");
  724. break;
  725. }
  726. break;
  727. }
  728. return n;
  729. }
  730. #define copy_from_user(to, from, n) \
  731. (__builtin_constant_p(n) ? \
  732. __constant_copy_from_user(to, from, n) : \
  733. __generic_copy_from_user(to, from, n))
  734. #define copy_to_user(to, from, n) \
  735. (__builtin_constant_p(n) ? \
  736. __constant_copy_to_user(to, from, n) : \
  737. __generic_copy_to_user(to, from, n))
  738. #define __copy_from_user(to, from, n) copy_from_user(to, from, n)
  739. #define __copy_to_user(to, from, n) copy_to_user(to, from, n)
  740. /*
  741. * Copy a null terminated string from userspace.
  742. */
  743. static inline long
  744. strncpy_from_user(char *dst, const char *src, long count)
  745. {
  746. long res;
  747. if (count == 0) return count;
  748. __asm__ __volatile__
  749. ("1: movesb (%2)+,%%d0\n"
  750. "12:moveb %%d0,(%1)+\n"
  751. " jeq 2f\n"
  752. " subql #1,%3\n"
  753. " jne 1b\n"
  754. "2: subl %3,%0\n"
  755. "3:\n"
  756. ".section .fixup,\"ax\"\n"
  757. " .even\n"
  758. "4: movel %4,%0\n"
  759. " jra 3b\n"
  760. ".previous\n"
  761. ".section __ex_table,\"a\"\n"
  762. " .align 4\n"
  763. " .long 1b,4b\n"
  764. " .long 12b,4b\n"
  765. ".previous"
  766. : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
  767. : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
  768. : "d0", "memory");
  769. return res;
  770. }
  771. /*
  772. * Return the size of a string (including the ending 0)
  773. *
  774. * Return 0 on exception, a value greater than N if too long
  775. */
  776. static inline long strnlen_user(const char *src, long n)
  777. {
  778. long res;
  779. res = -(long)src;
  780. __asm__ __volatile__
  781. ("1:\n"
  782. " tstl %2\n"
  783. " jeq 3f\n"
  784. "2: movesb (%1)+,%%d0\n"
  785. "22:\n"
  786. " subql #1,%2\n"
  787. " tstb %%d0\n"
  788. " jne 1b\n"
  789. " jra 4f\n"
  790. "3:\n"
  791. " addql #1,%0\n"
  792. "4:\n"
  793. " addl %1,%0\n"
  794. "5:\n"
  795. ".section .fixup,\"ax\"\n"
  796. " .even\n"
  797. "6: moveq %3,%0\n"
  798. " jra 5b\n"
  799. ".previous\n"
  800. ".section __ex_table,\"a\"\n"
  801. " .align 4\n"
  802. " .long 2b,6b\n"
  803. " .long 22b,6b\n"
  804. ".previous"
  805. : "=d"(res), "=a"(src), "=d"(n)
  806. : "i"(0), "0"(res), "1"(src), "2"(n)
  807. : "d0");
  808. return res;
  809. }
  810. #define strlen_user(str) strnlen_user(str, 32767)
  811. /*
  812. * Zero Userspace
  813. */
  814. static inline unsigned long
  815. clear_user(void *to, unsigned long n)
  816. {
  817. __asm__ __volatile__
  818. (" tstl %1\n"
  819. " jeq 3f\n"
  820. "1: movesl %3,(%0)+\n"
  821. "2: subql #1,%1\n"
  822. " jne 1b\n"
  823. "3: movel %2,%1\n"
  824. " bclr #1,%1\n"
  825. " jeq 4f\n"
  826. "24:movesw %3,(%0)+\n"
  827. "4: bclr #0,%1\n"
  828. " jeq 5f\n"
  829. "25:movesb %3,(%0)+\n"
  830. "5:\n"
  831. ".section .fixup,\"ax\"\n"
  832. " .even\n"
  833. "61:addql #1,%1\n"
  834. "6: lsll #2,%1\n"
  835. " addl %2,%1\n"
  836. " jra 5b\n"
  837. "7: addql #2,%1\n"
  838. " jra 5b\n"
  839. "8: addql #1,%1\n"
  840. " jra 5b\n"
  841. ".previous\n"
  842. ".section __ex_table,\"a\"\n"
  843. " .align 4\n"
  844. " .long 1b,61b\n"
  845. " .long 2b,6b\n"
  846. " .long 3b,61b\n"
  847. " .long 24b,7b\n"
  848. " .long 4b,7b\n"
  849. " .long 25b,8b\n"
  850. " .long 5b,8b\n"
  851. ".previous"
  852. : "=a"(to), "=d"(n)
  853. : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
  854. return n;
  855. }
  856. #endif /* _M68K_UACCESS_H */