ptrace_64.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* ptrace.c: Sparc process tracing support.
  3. *
  4. * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
  5. * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  6. *
  7. * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
  8. * and David Mosberger.
  9. *
  10. * Added Linux support -miguel (weird, eh?, the original code was meant
  11. * to emulate SunOS).
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/sched.h>
  15. #include <linux/sched/task_stack.h>
  16. #include <linux/mm.h>
  17. #include <linux/errno.h>
  18. #include <linux/export.h>
  19. #include <linux/ptrace.h>
  20. #include <linux/user.h>
  21. #include <linux/smp.h>
  22. #include <linux/security.h>
  23. #include <linux/seccomp.h>
  24. #include <linux/audit.h>
  25. #include <linux/signal.h>
  26. #include <linux/regset.h>
  27. #include <trace/syscall.h>
  28. #include <linux/compat.h>
  29. #include <linux/elf.h>
  30. #include <linux/context_tracking.h>
  31. #include <asm/asi.h>
  32. #include <linux/uaccess.h>
  33. #include <asm/psrcompat.h>
  34. #include <asm/visasm.h>
  35. #include <asm/spitfire.h>
  36. #include <asm/page.h>
  37. #include <asm/cpudata.h>
  38. #include <asm/cacheflush.h>
  39. #define CREATE_TRACE_POINTS
  40. #include <trace/events/syscalls.h>
  41. #include "entry.h"
  42. /* #define ALLOW_INIT_TRACING */
  43. struct pt_regs_offset {
  44. const char *name;
  45. int offset;
  46. };
  47. #define REG_OFFSET_NAME(n, r) \
  48. {.name = n, .offset = (PT_V9_##r)}
  49. #define REG_OFFSET_END {.name = NULL, .offset = 0}
  50. static const struct pt_regs_offset regoffset_table[] = {
  51. REG_OFFSET_NAME("g0", G0),
  52. REG_OFFSET_NAME("g1", G1),
  53. REG_OFFSET_NAME("g2", G2),
  54. REG_OFFSET_NAME("g3", G3),
  55. REG_OFFSET_NAME("g4", G4),
  56. REG_OFFSET_NAME("g5", G5),
  57. REG_OFFSET_NAME("g6", G6),
  58. REG_OFFSET_NAME("g7", G7),
  59. REG_OFFSET_NAME("i0", I0),
  60. REG_OFFSET_NAME("i1", I1),
  61. REG_OFFSET_NAME("i2", I2),
  62. REG_OFFSET_NAME("i3", I3),
  63. REG_OFFSET_NAME("i4", I4),
  64. REG_OFFSET_NAME("i5", I5),
  65. REG_OFFSET_NAME("i6", I6),
  66. REG_OFFSET_NAME("i7", I7),
  67. REG_OFFSET_NAME("tstate", TSTATE),
  68. REG_OFFSET_NAME("pc", TPC),
  69. REG_OFFSET_NAME("npc", TNPC),
  70. REG_OFFSET_NAME("y", Y),
  71. REG_OFFSET_NAME("lr", I7),
  72. REG_OFFSET_END,
  73. };
  74. /*
  75. * Called by kernel/ptrace.c when detaching..
  76. *
  77. * Make sure single step bits etc are not set.
  78. */
  79. void ptrace_disable(struct task_struct *child)
  80. {
  81. /* nothing to do */
  82. }
  83. /* To get the necessary page struct, access_process_vm() first calls
  84. * get_user_pages(). This has done a flush_dcache_page() on the
  85. * accessed page. Then our caller (copy_{to,from}_user_page()) did
  86. * to memcpy to read/write the data from that page.
  87. *
  88. * Now, the only thing we have to do is:
  89. * 1) flush the D-cache if it's possible than an illegal alias
  90. * has been created
  91. * 2) flush the I-cache if this is pre-cheetah and we did a write
  92. */
  93. void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
  94. unsigned long uaddr, void *kaddr,
  95. unsigned long len, int write)
  96. {
  97. BUG_ON(len > PAGE_SIZE);
  98. if (tlb_type == hypervisor)
  99. return;
  100. preempt_disable();
  101. #ifdef DCACHE_ALIASING_POSSIBLE
  102. /* If bit 13 of the kernel address we used to access the
  103. * user page is the same as the virtual address that page
  104. * is mapped to in the user's address space, we can skip the
  105. * D-cache flush.
  106. */
  107. if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
  108. unsigned long start = __pa(kaddr);
  109. unsigned long end = start + len;
  110. unsigned long dcache_line_size;
  111. dcache_line_size = local_cpu_data().dcache_line_size;
  112. if (tlb_type == spitfire) {
  113. for (; start < end; start += dcache_line_size)
  114. spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
  115. } else {
  116. start &= ~(dcache_line_size - 1);
  117. for (; start < end; start += dcache_line_size)
  118. __asm__ __volatile__(
  119. "stxa %%g0, [%0] %1\n\t"
  120. "membar #Sync"
  121. : /* no outputs */
  122. : "r" (start),
  123. "i" (ASI_DCACHE_INVALIDATE));
  124. }
  125. }
  126. #endif
  127. if (write && tlb_type == spitfire) {
  128. unsigned long start = (unsigned long) kaddr;
  129. unsigned long end = start + len;
  130. unsigned long icache_line_size;
  131. icache_line_size = local_cpu_data().icache_line_size;
  132. for (; start < end; start += icache_line_size)
  133. flushi(start);
  134. }
  135. preempt_enable();
  136. }
  137. EXPORT_SYMBOL_GPL(flush_ptrace_access);
  138. static int get_from_target(struct task_struct *target, unsigned long uaddr,
  139. void *kbuf, int len)
  140. {
  141. if (target == current) {
  142. if (copy_from_user(kbuf, (void __user *) uaddr, len))
  143. return -EFAULT;
  144. } else {
  145. int len2 = access_process_vm(target, uaddr, kbuf, len,
  146. FOLL_FORCE);
  147. if (len2 != len)
  148. return -EFAULT;
  149. }
  150. return 0;
  151. }
  152. static int set_to_target(struct task_struct *target, unsigned long uaddr,
  153. void *kbuf, int len)
  154. {
  155. if (target == current) {
  156. if (copy_to_user((void __user *) uaddr, kbuf, len))
  157. return -EFAULT;
  158. } else {
  159. int len2 = access_process_vm(target, uaddr, kbuf, len,
  160. FOLL_FORCE | FOLL_WRITE);
  161. if (len2 != len)
  162. return -EFAULT;
  163. }
  164. return 0;
  165. }
  166. static int regwindow64_get(struct task_struct *target,
  167. const struct pt_regs *regs,
  168. struct reg_window *wbuf)
  169. {
  170. unsigned long rw_addr = regs->u_regs[UREG_I6];
  171. if (!test_thread_64bit_stack(rw_addr)) {
  172. struct reg_window32 win32;
  173. int i;
  174. if (get_from_target(target, rw_addr, &win32, sizeof(win32)))
  175. return -EFAULT;
  176. for (i = 0; i < 8; i++)
  177. wbuf->locals[i] = win32.locals[i];
  178. for (i = 0; i < 8; i++)
  179. wbuf->ins[i] = win32.ins[i];
  180. } else {
  181. rw_addr += STACK_BIAS;
  182. if (get_from_target(target, rw_addr, wbuf, sizeof(*wbuf)))
  183. return -EFAULT;
  184. }
  185. return 0;
  186. }
  187. static int regwindow64_set(struct task_struct *target,
  188. const struct pt_regs *regs,
  189. struct reg_window *wbuf)
  190. {
  191. unsigned long rw_addr = regs->u_regs[UREG_I6];
  192. if (!test_thread_64bit_stack(rw_addr)) {
  193. struct reg_window32 win32;
  194. int i;
  195. for (i = 0; i < 8; i++)
  196. win32.locals[i] = wbuf->locals[i];
  197. for (i = 0; i < 8; i++)
  198. win32.ins[i] = wbuf->ins[i];
  199. if (set_to_target(target, rw_addr, &win32, sizeof(win32)))
  200. return -EFAULT;
  201. } else {
  202. rw_addr += STACK_BIAS;
  203. if (set_to_target(target, rw_addr, wbuf, sizeof(*wbuf)))
  204. return -EFAULT;
  205. }
  206. return 0;
  207. }
  208. enum sparc_regset {
  209. REGSET_GENERAL,
  210. REGSET_FP,
  211. };
  212. static int genregs64_get(struct task_struct *target,
  213. const struct user_regset *regset,
  214. struct membuf to)
  215. {
  216. const struct pt_regs *regs = task_pt_regs(target);
  217. struct reg_window window;
  218. if (target == current)
  219. flushw_user();
  220. membuf_write(&to, regs->u_regs, 16 * sizeof(u64));
  221. if (!to.left)
  222. return 0;
  223. if (regwindow64_get(target, regs, &window))
  224. return -EFAULT;
  225. membuf_write(&to, &window, 16 * sizeof(u64));
  226. /* TSTATE, TPC, TNPC */
  227. membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
  228. return membuf_store(&to, (u64)regs->y);
  229. }
  230. static int genregs64_set(struct task_struct *target,
  231. const struct user_regset *regset,
  232. unsigned int pos, unsigned int count,
  233. const void *kbuf, const void __user *ubuf)
  234. {
  235. struct pt_regs *regs = task_pt_regs(target);
  236. int ret;
  237. if (target == current)
  238. flushw_user();
  239. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  240. regs->u_regs,
  241. 0, 16 * sizeof(u64));
  242. if (!ret && count && pos < (32 * sizeof(u64))) {
  243. struct reg_window window;
  244. if (regwindow64_get(target, regs, &window))
  245. return -EFAULT;
  246. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  247. &window,
  248. 16 * sizeof(u64),
  249. 32 * sizeof(u64));
  250. if (!ret &&
  251. regwindow64_set(target, regs, &window))
  252. return -EFAULT;
  253. }
  254. if (!ret && count > 0) {
  255. unsigned long tstate;
  256. /* TSTATE */
  257. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  258. &tstate,
  259. 32 * sizeof(u64),
  260. 33 * sizeof(u64));
  261. if (!ret) {
  262. /* Only the condition codes and the "in syscall"
  263. * state can be modified in the %tstate register.
  264. */
  265. tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
  266. regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
  267. regs->tstate |= tstate;
  268. }
  269. }
  270. if (!ret) {
  271. /* TPC, TNPC */
  272. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  273. &regs->tpc,
  274. 33 * sizeof(u64),
  275. 35 * sizeof(u64));
  276. }
  277. if (!ret) {
  278. unsigned long y = regs->y;
  279. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  280. &y,
  281. 35 * sizeof(u64),
  282. 36 * sizeof(u64));
  283. if (!ret)
  284. regs->y = y;
  285. }
  286. if (!ret)
  287. user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
  288. 36 * sizeof(u64), -1);
  289. return ret;
  290. }
  291. static int fpregs64_get(struct task_struct *target,
  292. const struct user_regset *regset,
  293. struct membuf to)
  294. {
  295. struct thread_info *t = task_thread_info(target);
  296. unsigned long fprs;
  297. if (target == current)
  298. save_and_clear_fpu();
  299. fprs = t->fpsaved[0];
  300. if (fprs & FPRS_DL)
  301. membuf_write(&to, t->fpregs, 16 * sizeof(u64));
  302. else
  303. membuf_zero(&to, 16 * sizeof(u64));
  304. if (fprs & FPRS_DU)
  305. membuf_write(&to, t->fpregs + 16, 16 * sizeof(u64));
  306. else
  307. membuf_zero(&to, 16 * sizeof(u64));
  308. if (fprs & FPRS_FEF) {
  309. membuf_store(&to, t->xfsr[0]);
  310. membuf_store(&to, t->gsr[0]);
  311. } else {
  312. membuf_zero(&to, 2 * sizeof(u64));
  313. }
  314. return membuf_store(&to, fprs);
  315. }
  316. static int fpregs64_set(struct task_struct *target,
  317. const struct user_regset *regset,
  318. unsigned int pos, unsigned int count,
  319. const void *kbuf, const void __user *ubuf)
  320. {
  321. unsigned long *fpregs = task_thread_info(target)->fpregs;
  322. unsigned long fprs;
  323. int ret;
  324. if (target == current)
  325. save_and_clear_fpu();
  326. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  327. fpregs,
  328. 0, 32 * sizeof(u64));
  329. if (!ret)
  330. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  331. task_thread_info(target)->xfsr,
  332. 32 * sizeof(u64),
  333. 33 * sizeof(u64));
  334. if (!ret)
  335. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  336. task_thread_info(target)->gsr,
  337. 33 * sizeof(u64),
  338. 34 * sizeof(u64));
  339. fprs = task_thread_info(target)->fpsaved[0];
  340. if (!ret && count > 0) {
  341. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  342. &fprs,
  343. 34 * sizeof(u64),
  344. 35 * sizeof(u64));
  345. }
  346. fprs |= (FPRS_FEF | FPRS_DL | FPRS_DU);
  347. task_thread_info(target)->fpsaved[0] = fprs;
  348. if (!ret)
  349. user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
  350. 35 * sizeof(u64), -1);
  351. return ret;
  352. }
  353. static const struct user_regset sparc64_regsets[] = {
  354. /* Format is:
  355. * G0 --> G7
  356. * O0 --> O7
  357. * L0 --> L7
  358. * I0 --> I7
  359. * TSTATE, TPC, TNPC, Y
  360. */
  361. [REGSET_GENERAL] = {
  362. .core_note_type = NT_PRSTATUS,
  363. .n = 36,
  364. .size = sizeof(u64), .align = sizeof(u64),
  365. .regset_get = genregs64_get, .set = genregs64_set
  366. },
  367. /* Format is:
  368. * F0 --> F63
  369. * FSR
  370. * GSR
  371. * FPRS
  372. */
  373. [REGSET_FP] = {
  374. .core_note_type = NT_PRFPREG,
  375. .n = 35,
  376. .size = sizeof(u64), .align = sizeof(u64),
  377. .regset_get = fpregs64_get, .set = fpregs64_set
  378. },
  379. };
  380. static int getregs64_get(struct task_struct *target,
  381. const struct user_regset *regset,
  382. struct membuf to)
  383. {
  384. const struct pt_regs *regs = task_pt_regs(target);
  385. if (target == current)
  386. flushw_user();
  387. membuf_write(&to, regs->u_regs + 1, 15 * sizeof(u64));
  388. membuf_store(&to, (u64)0);
  389. membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
  390. return membuf_store(&to, (u64)regs->y);
  391. }
  392. static int setregs64_set(struct task_struct *target,
  393. const struct user_regset *regset,
  394. unsigned int pos, unsigned int count,
  395. const void *kbuf, const void __user *ubuf)
  396. {
  397. struct pt_regs *regs = task_pt_regs(target);
  398. unsigned long y = regs->y;
  399. unsigned long tstate;
  400. int ret;
  401. if (target == current)
  402. flushw_user();
  403. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  404. regs->u_regs + 1,
  405. 0 * sizeof(u64),
  406. 15 * sizeof(u64));
  407. if (ret)
  408. return ret;
  409. user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
  410. 15 * sizeof(u64), 16 * sizeof(u64));
  411. /* TSTATE */
  412. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  413. &tstate,
  414. 16 * sizeof(u64),
  415. 17 * sizeof(u64));
  416. if (ret)
  417. return ret;
  418. /* Only the condition codes and the "in syscall"
  419. * state can be modified in the %tstate register.
  420. */
  421. tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
  422. regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
  423. regs->tstate |= tstate;
  424. /* TPC, TNPC */
  425. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  426. &regs->tpc,
  427. 17 * sizeof(u64),
  428. 19 * sizeof(u64));
  429. if (ret)
  430. return ret;
  431. /* Y */
  432. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  433. &y,
  434. 19 * sizeof(u64),
  435. 20 * sizeof(u64));
  436. if (!ret)
  437. regs->y = y;
  438. return ret;
  439. }
  440. static const struct user_regset ptrace64_regsets[] = {
  441. /* Format is:
  442. * G1 --> G7
  443. * O0 --> O7
  444. * 0
  445. * TSTATE, TPC, TNPC, Y
  446. */
  447. [REGSET_GENERAL] = {
  448. .n = 20, .size = sizeof(u64),
  449. .regset_get = getregs64_get, .set = setregs64_set,
  450. },
  451. };
  452. static const struct user_regset_view ptrace64_view = {
  453. .regsets = ptrace64_regsets, .n = ARRAY_SIZE(ptrace64_regsets)
  454. };
  455. static const struct user_regset_view user_sparc64_view = {
  456. .name = "sparc64", .e_machine = EM_SPARCV9,
  457. .regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets)
  458. };
  459. #ifdef CONFIG_COMPAT
  460. static int genregs32_get(struct task_struct *target,
  461. const struct user_regset *regset,
  462. struct membuf to)
  463. {
  464. const struct pt_regs *regs = task_pt_regs(target);
  465. u32 uregs[16];
  466. int i;
  467. if (target == current)
  468. flushw_user();
  469. for (i = 0; i < 16; i++)
  470. membuf_store(&to, (u32)regs->u_regs[i]);
  471. if (!to.left)
  472. return 0;
  473. if (get_from_target(target, regs->u_regs[UREG_I6],
  474. uregs, sizeof(uregs)))
  475. return -EFAULT;
  476. membuf_write(&to, uregs, 16 * sizeof(u32));
  477. membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
  478. membuf_store(&to, (u32)(regs->tpc));
  479. membuf_store(&to, (u32)(regs->tnpc));
  480. membuf_store(&to, (u32)(regs->y));
  481. return membuf_zero(&to, 2 * sizeof(u32));
  482. }
  483. static int genregs32_set(struct task_struct *target,
  484. const struct user_regset *regset,
  485. unsigned int pos, unsigned int count,
  486. const void *kbuf, const void __user *ubuf)
  487. {
  488. struct pt_regs *regs = task_pt_regs(target);
  489. compat_ulong_t __user *reg_window;
  490. const compat_ulong_t *k = kbuf;
  491. const compat_ulong_t __user *u = ubuf;
  492. compat_ulong_t reg;
  493. if (target == current)
  494. flushw_user();
  495. pos /= sizeof(reg);
  496. count /= sizeof(reg);
  497. if (kbuf) {
  498. for (; count > 0 && pos < 16; count--)
  499. regs->u_regs[pos++] = *k++;
  500. reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
  501. reg_window -= 16;
  502. if (target == current) {
  503. for (; count > 0 && pos < 32; count--) {
  504. if (put_user(*k++, &reg_window[pos++]))
  505. return -EFAULT;
  506. }
  507. } else {
  508. for (; count > 0 && pos < 32; count--) {
  509. if (access_process_vm(target,
  510. (unsigned long)
  511. &reg_window[pos],
  512. (void *) k,
  513. sizeof(*k),
  514. FOLL_FORCE | FOLL_WRITE)
  515. != sizeof(*k))
  516. return -EFAULT;
  517. k++;
  518. pos++;
  519. }
  520. }
  521. } else {
  522. for (; count > 0 && pos < 16; count--) {
  523. if (get_user(reg, u++))
  524. return -EFAULT;
  525. regs->u_regs[pos++] = reg;
  526. }
  527. reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
  528. reg_window -= 16;
  529. if (target == current) {
  530. for (; count > 0 && pos < 32; count--) {
  531. if (get_user(reg, u++) ||
  532. put_user(reg, &reg_window[pos++]))
  533. return -EFAULT;
  534. }
  535. } else {
  536. for (; count > 0 && pos < 32; count--) {
  537. if (get_user(reg, u++))
  538. return -EFAULT;
  539. if (access_process_vm(target,
  540. (unsigned long)
  541. &reg_window[pos],
  542. &reg, sizeof(reg),
  543. FOLL_FORCE | FOLL_WRITE)
  544. != sizeof(reg))
  545. return -EFAULT;
  546. pos++;
  547. u++;
  548. }
  549. }
  550. }
  551. while (count > 0) {
  552. unsigned long tstate;
  553. if (kbuf)
  554. reg = *k++;
  555. else if (get_user(reg, u++))
  556. return -EFAULT;
  557. switch (pos) {
  558. case 32: /* PSR */
  559. tstate = regs->tstate;
  560. tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
  561. tstate |= psr_to_tstate_icc(reg);
  562. if (reg & PSR_SYSCALL)
  563. tstate |= TSTATE_SYSCALL;
  564. regs->tstate = tstate;
  565. break;
  566. case 33: /* PC */
  567. regs->tpc = reg;
  568. break;
  569. case 34: /* NPC */
  570. regs->tnpc = reg;
  571. break;
  572. case 35: /* Y */
  573. regs->y = reg;
  574. break;
  575. case 36: /* WIM */
  576. case 37: /* TBR */
  577. break;
  578. default:
  579. goto finish;
  580. }
  581. pos++;
  582. count--;
  583. }
  584. finish:
  585. pos *= sizeof(reg);
  586. count *= sizeof(reg);
  587. user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
  588. 38 * sizeof(reg), -1);
  589. return 0;
  590. }
  591. static int fpregs32_get(struct task_struct *target,
  592. const struct user_regset *regset,
  593. struct membuf to)
  594. {
  595. struct thread_info *t = task_thread_info(target);
  596. bool enabled;
  597. if (target == current)
  598. save_and_clear_fpu();
  599. enabled = t->fpsaved[0] & FPRS_FEF;
  600. membuf_write(&to, t->fpregs, 32 * sizeof(u32));
  601. membuf_zero(&to, sizeof(u32));
  602. if (enabled)
  603. membuf_store(&to, (u32)t->xfsr[0]);
  604. else
  605. membuf_zero(&to, sizeof(u32));
  606. membuf_store(&to, (u32)((enabled << 8) | (8 << 16)));
  607. return membuf_zero(&to, 64 * sizeof(u32));
  608. }
  609. static int fpregs32_set(struct task_struct *target,
  610. const struct user_regset *regset,
  611. unsigned int pos, unsigned int count,
  612. const void *kbuf, const void __user *ubuf)
  613. {
  614. unsigned long *fpregs = task_thread_info(target)->fpregs;
  615. unsigned long fprs;
  616. int ret;
  617. if (target == current)
  618. save_and_clear_fpu();
  619. fprs = task_thread_info(target)->fpsaved[0];
  620. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  621. fpregs,
  622. 0, 32 * sizeof(u32));
  623. if (!ret)
  624. user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
  625. 32 * sizeof(u32),
  626. 33 * sizeof(u32));
  627. if (!ret && count > 0) {
  628. compat_ulong_t fsr;
  629. unsigned long val;
  630. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  631. &fsr,
  632. 33 * sizeof(u32),
  633. 34 * sizeof(u32));
  634. if (!ret) {
  635. val = task_thread_info(target)->xfsr[0];
  636. val &= 0xffffffff00000000UL;
  637. val |= fsr;
  638. task_thread_info(target)->xfsr[0] = val;
  639. }
  640. }
  641. fprs |= (FPRS_FEF | FPRS_DL);
  642. task_thread_info(target)->fpsaved[0] = fprs;
  643. if (!ret)
  644. user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
  645. 34 * sizeof(u32), -1);
  646. return ret;
  647. }
  648. static const struct user_regset sparc32_regsets[] = {
  649. /* Format is:
  650. * G0 --> G7
  651. * O0 --> O7
  652. * L0 --> L7
  653. * I0 --> I7
  654. * PSR, PC, nPC, Y, WIM, TBR
  655. */
  656. [REGSET_GENERAL] = {
  657. .core_note_type = NT_PRSTATUS,
  658. .n = 38,
  659. .size = sizeof(u32), .align = sizeof(u32),
  660. .regset_get = genregs32_get, .set = genregs32_set
  661. },
  662. /* Format is:
  663. * F0 --> F31
  664. * empty 32-bit word
  665. * FSR (32--bit word)
  666. * FPU QUEUE COUNT (8-bit char)
  667. * FPU QUEUE ENTRYSIZE (8-bit char)
  668. * FPU ENABLED (8-bit char)
  669. * empty 8-bit char
  670. * FPU QUEUE (64 32-bit ints)
  671. */
  672. [REGSET_FP] = {
  673. .core_note_type = NT_PRFPREG,
  674. .n = 99,
  675. .size = sizeof(u32), .align = sizeof(u32),
  676. .regset_get = fpregs32_get, .set = fpregs32_set
  677. },
  678. };
  679. static int getregs_get(struct task_struct *target,
  680. const struct user_regset *regset,
  681. struct membuf to)
  682. {
  683. const struct pt_regs *regs = task_pt_regs(target);
  684. int i;
  685. if (target == current)
  686. flushw_user();
  687. membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
  688. membuf_store(&to, (u32)(regs->tpc));
  689. membuf_store(&to, (u32)(regs->tnpc));
  690. membuf_store(&to, (u32)(regs->y));
  691. for (i = 1; i < 16; i++)
  692. membuf_store(&to, (u32)regs->u_regs[i]);
  693. return to.left;
  694. }
  695. static int setregs_set(struct task_struct *target,
  696. const struct user_regset *regset,
  697. unsigned int pos, unsigned int count,
  698. const void *kbuf, const void __user *ubuf)
  699. {
  700. struct pt_regs *regs = task_pt_regs(target);
  701. unsigned long tstate;
  702. u32 uregs[19];
  703. int i, ret;
  704. if (target == current)
  705. flushw_user();
  706. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  707. uregs,
  708. 0, 19 * sizeof(u32));
  709. if (ret)
  710. return ret;
  711. tstate = regs->tstate;
  712. tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
  713. tstate |= psr_to_tstate_icc(uregs[0]);
  714. if (uregs[0] & PSR_SYSCALL)
  715. tstate |= TSTATE_SYSCALL;
  716. regs->tstate = tstate;
  717. regs->tpc = uregs[1];
  718. regs->tnpc = uregs[2];
  719. regs->y = uregs[3];
  720. for (i = 1; i < 15; i++)
  721. regs->u_regs[i] = uregs[3 + i];
  722. return 0;
  723. }
  724. static int getfpregs_get(struct task_struct *target,
  725. const struct user_regset *regset,
  726. struct membuf to)
  727. {
  728. struct thread_info *t = task_thread_info(target);
  729. if (target == current)
  730. save_and_clear_fpu();
  731. membuf_write(&to, t->fpregs, 32 * sizeof(u32));
  732. if (t->fpsaved[0] & FPRS_FEF)
  733. membuf_store(&to, (u32)t->xfsr[0]);
  734. else
  735. membuf_zero(&to, sizeof(u32));
  736. return membuf_zero(&to, 35 * sizeof(u32));
  737. }
  738. static int setfpregs_set(struct task_struct *target,
  739. const struct user_regset *regset,
  740. unsigned int pos, unsigned int count,
  741. const void *kbuf, const void __user *ubuf)
  742. {
  743. unsigned long *fpregs = task_thread_info(target)->fpregs;
  744. unsigned long fprs;
  745. int ret;
  746. if (target == current)
  747. save_and_clear_fpu();
  748. fprs = task_thread_info(target)->fpsaved[0];
  749. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  750. fpregs,
  751. 0, 32 * sizeof(u32));
  752. if (!ret) {
  753. compat_ulong_t fsr;
  754. unsigned long val;
  755. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  756. &fsr,
  757. 32 * sizeof(u32),
  758. 33 * sizeof(u32));
  759. if (!ret) {
  760. val = task_thread_info(target)->xfsr[0];
  761. val &= 0xffffffff00000000UL;
  762. val |= fsr;
  763. task_thread_info(target)->xfsr[0] = val;
  764. }
  765. }
  766. fprs |= (FPRS_FEF | FPRS_DL);
  767. task_thread_info(target)->fpsaved[0] = fprs;
  768. return ret;
  769. }
  770. static const struct user_regset ptrace32_regsets[] = {
  771. [REGSET_GENERAL] = {
  772. .n = 19, .size = sizeof(u32),
  773. .regset_get = getregs_get, .set = setregs_set,
  774. },
  775. [REGSET_FP] = {
  776. .n = 68, .size = sizeof(u32),
  777. .regset_get = getfpregs_get, .set = setfpregs_set,
  778. },
  779. };
  780. static const struct user_regset_view ptrace32_view = {
  781. .regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets)
  782. };
  783. static const struct user_regset_view user_sparc32_view = {
  784. .name = "sparc", .e_machine = EM_SPARC,
  785. .regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
  786. };
  787. #endif /* CONFIG_COMPAT */
  788. const struct user_regset_view *task_user_regset_view(struct task_struct *task)
  789. {
  790. #ifdef CONFIG_COMPAT
  791. if (test_tsk_thread_flag(task, TIF_32BIT))
  792. return &user_sparc32_view;
  793. #endif
  794. return &user_sparc64_view;
  795. }
  796. #ifdef CONFIG_COMPAT
  797. struct compat_fps {
  798. unsigned int regs[32];
  799. unsigned int fsr;
  800. unsigned int flags;
  801. unsigned int extra;
  802. unsigned int fpqd;
  803. struct compat_fq {
  804. unsigned int insnaddr;
  805. unsigned int insn;
  806. } fpq[16];
  807. };
  808. long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
  809. compat_ulong_t caddr, compat_ulong_t cdata)
  810. {
  811. compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
  812. struct pt_regs32 __user *pregs;
  813. struct compat_fps __user *fps;
  814. unsigned long addr2 = caddr2;
  815. unsigned long addr = caddr;
  816. unsigned long data = cdata;
  817. int ret;
  818. pregs = (struct pt_regs32 __user *) addr;
  819. fps = (struct compat_fps __user *) addr;
  820. switch (request) {
  821. case PTRACE_PEEKUSR:
  822. ret = (addr != 0) ? -EIO : 0;
  823. break;
  824. case PTRACE_GETREGS:
  825. ret = copy_regset_to_user(child, &ptrace32_view,
  826. REGSET_GENERAL, 0,
  827. 19 * sizeof(u32),
  828. pregs);
  829. break;
  830. case PTRACE_SETREGS:
  831. ret = copy_regset_from_user(child, &ptrace32_view,
  832. REGSET_GENERAL, 0,
  833. 19 * sizeof(u32),
  834. pregs);
  835. break;
  836. case PTRACE_GETFPREGS:
  837. ret = copy_regset_to_user(child, &ptrace32_view,
  838. REGSET_FP, 0,
  839. 68 * sizeof(u32),
  840. fps);
  841. break;
  842. case PTRACE_SETFPREGS:
  843. ret = copy_regset_from_user(child, &ptrace32_view,
  844. REGSET_FP, 0,
  845. 33 * sizeof(u32),
  846. fps);
  847. break;
  848. case PTRACE_READTEXT:
  849. case PTRACE_READDATA:
  850. ret = ptrace_readdata(child, addr,
  851. (char __user *)addr2, data);
  852. if (ret == data)
  853. ret = 0;
  854. else if (ret >= 0)
  855. ret = -EIO;
  856. break;
  857. case PTRACE_WRITETEXT:
  858. case PTRACE_WRITEDATA:
  859. ret = ptrace_writedata(child, (char __user *) addr2,
  860. addr, data);
  861. if (ret == data)
  862. ret = 0;
  863. else if (ret >= 0)
  864. ret = -EIO;
  865. break;
  866. default:
  867. if (request == PTRACE_SPARC_DETACH)
  868. request = PTRACE_DETACH;
  869. ret = compat_ptrace_request(child, request, addr, data);
  870. break;
  871. }
  872. return ret;
  873. }
  874. #endif /* CONFIG_COMPAT */
  875. struct fps {
  876. unsigned int regs[64];
  877. unsigned long fsr;
  878. };
  879. long arch_ptrace(struct task_struct *child, long request,
  880. unsigned long addr, unsigned long data)
  881. {
  882. const struct user_regset_view *view = task_user_regset_view(current);
  883. unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
  884. struct pt_regs __user *pregs;
  885. struct fps __user *fps;
  886. void __user *addr2p;
  887. int ret;
  888. pregs = (struct pt_regs __user *) addr;
  889. fps = (struct fps __user *) addr;
  890. addr2p = (void __user *) addr2;
  891. switch (request) {
  892. case PTRACE_PEEKUSR:
  893. ret = (addr != 0) ? -EIO : 0;
  894. break;
  895. case PTRACE_GETREGS64:
  896. ret = copy_regset_to_user(child, &ptrace64_view,
  897. REGSET_GENERAL, 0,
  898. 19 * sizeof(u64),
  899. pregs);
  900. break;
  901. case PTRACE_SETREGS64:
  902. ret = copy_regset_from_user(child, &ptrace64_view,
  903. REGSET_GENERAL, 0,
  904. 19 * sizeof(u64),
  905. pregs);
  906. break;
  907. case PTRACE_GETFPREGS64:
  908. ret = copy_regset_to_user(child, view, REGSET_FP,
  909. 0 * sizeof(u64),
  910. 33 * sizeof(u64),
  911. fps);
  912. break;
  913. case PTRACE_SETFPREGS64:
  914. ret = copy_regset_from_user(child, view, REGSET_FP,
  915. 0 * sizeof(u64),
  916. 33 * sizeof(u64),
  917. fps);
  918. break;
  919. case PTRACE_READTEXT:
  920. case PTRACE_READDATA:
  921. ret = ptrace_readdata(child, addr, addr2p, data);
  922. if (ret == data)
  923. ret = 0;
  924. else if (ret >= 0)
  925. ret = -EIO;
  926. break;
  927. case PTRACE_WRITETEXT:
  928. case PTRACE_WRITEDATA:
  929. ret = ptrace_writedata(child, addr2p, addr, data);
  930. if (ret == data)
  931. ret = 0;
  932. else if (ret >= 0)
  933. ret = -EIO;
  934. break;
  935. default:
  936. if (request == PTRACE_SPARC_DETACH)
  937. request = PTRACE_DETACH;
  938. ret = ptrace_request(child, request, addr, data);
  939. break;
  940. }
  941. return ret;
  942. }
  943. asmlinkage int syscall_trace_enter(struct pt_regs *regs)
  944. {
  945. int ret = 0;
  946. /* do the secure computing check first */
  947. secure_computing_strict(regs->u_regs[UREG_G1]);
  948. if (test_thread_flag(TIF_NOHZ))
  949. user_exit();
  950. if (test_thread_flag(TIF_SYSCALL_TRACE))
  951. ret = ptrace_report_syscall_entry(regs);
  952. if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
  953. trace_sys_enter(regs, regs->u_regs[UREG_G1]);
  954. audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0],
  955. regs->u_regs[UREG_I1], regs->u_regs[UREG_I2],
  956. regs->u_regs[UREG_I3]);
  957. return ret;
  958. }
  959. asmlinkage void syscall_trace_leave(struct pt_regs *regs)
  960. {
  961. if (test_thread_flag(TIF_NOHZ))
  962. user_exit();
  963. audit_syscall_exit(regs);
  964. if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
  965. trace_sys_exit(regs, regs->u_regs[UREG_I0]);
  966. if (test_thread_flag(TIF_SYSCALL_TRACE))
  967. ptrace_report_syscall_exit(regs, 0);
  968. if (test_thread_flag(TIF_NOHZ))
  969. user_enter();
  970. }
  971. /**
  972. * regs_query_register_offset() - query register offset from its name
  973. * @name: the name of a register
  974. *
  975. * regs_query_register_offset() returns the offset of a register in struct
  976. * pt_regs from its name. If the name is invalid, this returns -EINVAL;
  977. */
  978. int regs_query_register_offset(const char *name)
  979. {
  980. const struct pt_regs_offset *roff;
  981. for (roff = regoffset_table; roff->name != NULL; roff++)
  982. if (!strcmp(roff->name, name))
  983. return roff->offset;
  984. return -EINVAL;
  985. }
  986. /**
  987. * regs_within_kernel_stack() - check the address in the stack
  988. * @regs: pt_regs which contains kernel stack pointer.
  989. * @addr: address which is checked.
  990. *
  991. * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
  992. * If @addr is within the kernel stack, it returns true. If not, returns false.
  993. */
  994. static inline int regs_within_kernel_stack(struct pt_regs *regs,
  995. unsigned long addr)
  996. {
  997. unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
  998. return ((addr & ~(THREAD_SIZE - 1)) ==
  999. (ksp & ~(THREAD_SIZE - 1)));
  1000. }
  1001. /**
  1002. * regs_get_kernel_stack_nth() - get Nth entry of the stack
  1003. * @regs: pt_regs which contains kernel stack pointer.
  1004. * @n: stack entry number.
  1005. *
  1006. * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
  1007. * is specified by @regs. If the @n th entry is NOT in the kernel stack,
  1008. * this returns 0.
  1009. */
  1010. unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
  1011. {
  1012. unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
  1013. unsigned long *addr = (unsigned long *)ksp;
  1014. addr += n;
  1015. if (regs_within_kernel_stack(regs, (unsigned long)addr))
  1016. return *addr;
  1017. else
  1018. return 0;
  1019. }