ptrace-altivec.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. #include <linux/regset.h>
  3. #include <linux/elf.h>
  4. #include <asm/switch_to.h>
  5. #include "ptrace-decl.h"
  6. /*
  7. * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
  8. * The transfer totals 34 quadword. Quadwords 0-31 contain the
  9. * corresponding vector registers. Quadword 32 contains the vscr as the
  10. * last word (offset 12) within that quadword. Quadword 33 contains the
  11. * vrsave as the first word (offset 0) within the quadword.
  12. *
  13. * This definition of the VMX state is compatible with the current PPC32
  14. * ptrace interface. This allows signal handling and ptrace to use the
  15. * same structures. This also simplifies the implementation of a bi-arch
  16. * (combined (32- and 64-bit) gdb.
  17. */
  18. int vr_active(struct task_struct *target, const struct user_regset *regset)
  19. {
  20. flush_altivec_to_thread(target);
  21. return target->thread.used_vr ? regset->n : 0;
  22. }
  23. /*
  24. * Regardless of transactions, 'vr_state' holds the current running
  25. * value of all the VMX registers and 'ckvr_state' holds the last
  26. * checkpointed value of all the VMX registers for the current
  27. * transaction to fall back on in case it aborts.
  28. *
  29. * Userspace interface buffer layout:
  30. *
  31. * struct data {
  32. * vector128 vr[32];
  33. * vector128 vscr;
  34. * vector128 vrsave;
  35. * };
  36. */
  37. int vr_get(struct task_struct *target, const struct user_regset *regset,
  38. struct membuf to)
  39. {
  40. union {
  41. elf_vrreg_t reg;
  42. u32 word;
  43. } vrsave;
  44. flush_altivec_to_thread(target);
  45. BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
  46. offsetof(struct thread_vr_state, vr[32]));
  47. membuf_write(&to, &target->thread.vr_state, 33 * sizeof(vector128));
  48. /*
  49. * Copy out only the low-order word of vrsave.
  50. */
  51. memset(&vrsave, 0, sizeof(vrsave));
  52. vrsave.word = target->thread.vrsave;
  53. return membuf_write(&to, &vrsave, sizeof(vrsave));
  54. }
  55. /*
  56. * Regardless of transactions, 'vr_state' holds the current running
  57. * value of all the VMX registers and 'ckvr_state' holds the last
  58. * checkpointed value of all the VMX registers for the current
  59. * transaction to fall back on in case it aborts.
  60. *
  61. * Userspace interface buffer layout:
  62. *
  63. * struct data {
  64. * vector128 vr[32];
  65. * vector128 vscr;
  66. * vector128 vrsave;
  67. * };
  68. */
  69. int vr_set(struct task_struct *target, const struct user_regset *regset,
  70. unsigned int pos, unsigned int count,
  71. const void *kbuf, const void __user *ubuf)
  72. {
  73. int ret;
  74. flush_altivec_to_thread(target);
  75. BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
  76. offsetof(struct thread_vr_state, vr[32]));
  77. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
  78. &target->thread.vr_state, 0,
  79. 33 * sizeof(vector128));
  80. if (!ret && count > 0) {
  81. /*
  82. * We use only the first word of vrsave.
  83. */
  84. int start, end;
  85. union {
  86. elf_vrreg_t reg;
  87. u32 word;
  88. } vrsave;
  89. memset(&vrsave, 0, sizeof(vrsave));
  90. vrsave.word = target->thread.vrsave;
  91. start = 33 * sizeof(vector128);
  92. end = start + sizeof(vrsave);
  93. ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
  94. start, end);
  95. if (!ret)
  96. target->thread.vrsave = vrsave.word;
  97. }
  98. return ret;
  99. }