uaccess.h 21 KB

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