uaccess.h 21 KB

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