1 // SPDX-License-Identifier: GPL-2.0-or-later
3 #include <linux/regset.h>
5 #include <asm/switch_to.h>
7 #include <asm/asm-prototypes.h>
9 #include "ptrace-decl.h"
11 void flush_tmregs_to_thread(struct task_struct *tsk)
14 * If task is not current, it will have been flushed already to
15 * it's thread_struct during __switch_to().
17 * A reclaim flushes ALL the state or if not in TM save TM SPRs
18 * in the appropriate thread structures from live.
21 if (!cpu_has_feature(CPU_FTR_TM) || tsk != current)
24 if (MSR_TM_SUSPENDED(mfmsr())) {
25 tm_reclaim_current(TM_CAUSE_SIGNAL);
28 tm_save_sprs(&tsk->thread);
32 static unsigned long get_user_ckpt_msr(struct task_struct *task)
34 return task->thread.ckpt_regs.msr | task->thread.fpexc_mode;
37 static int set_user_ckpt_msr(struct task_struct *task, unsigned long msr)
39 task->thread.ckpt_regs.msr &= ~MSR_DEBUGCHANGE;
40 task->thread.ckpt_regs.msr |= msr & MSR_DEBUGCHANGE;
44 static int set_user_ckpt_trap(struct task_struct *task, unsigned long trap)
46 set_trap(&task->thread.ckpt_regs, trap);
51 * tm_cgpr_active - get active number of registers in CGPR
52 * @target: The target task.
53 * @regset: The user regset structure.
55 * This function checks for the active number of available
56 * regisers in transaction checkpointed GPR category.
58 int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset)
60 if (!cpu_has_feature(CPU_FTR_TM))
63 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
70 * tm_cgpr_get - get CGPR registers
71 * @target: The target task.
72 * @regset: The user regset structure.
73 * @pos: The buffer position.
74 * @count: Number of bytes to copy.
75 * @kbuf: Kernel buffer to copy from.
76 * @ubuf: User buffer to copy into.
78 * This function gets transaction checkpointed GPR registers.
80 * When the transaction is active, 'ckpt_regs' holds all the checkpointed
81 * GPR register values for the current transaction to fall back on if it
82 * aborts in between. This function gets those checkpointed GPR registers.
83 * The userspace interface buffer layout is as follows.
86 * struct pt_regs ckpt_regs;
89 int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
90 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
94 if (!cpu_has_feature(CPU_FTR_TM))
97 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
100 flush_tmregs_to_thread(target);
101 flush_fp_to_thread(target);
102 flush_altivec_to_thread(target);
104 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
105 &target->thread.ckpt_regs,
106 0, offsetof(struct pt_regs, msr));
108 unsigned long msr = get_user_ckpt_msr(target);
110 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr,
111 offsetof(struct pt_regs, msr),
112 offsetof(struct pt_regs, msr) +
116 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
117 offsetof(struct pt_regs, msr) + sizeof(long));
120 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
121 &target->thread.ckpt_regs.orig_gpr3,
122 offsetof(struct pt_regs, orig_gpr3),
123 sizeof(struct user_pt_regs));
125 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
126 sizeof(struct user_pt_regs), -1);
132 * tm_cgpr_set - set the CGPR registers
133 * @target: The target task.
134 * @regset: The user regset structure.
135 * @pos: The buffer position.
136 * @count: Number of bytes to copy.
137 * @kbuf: Kernel buffer to copy into.
138 * @ubuf: User buffer to copy from.
140 * This function sets in transaction checkpointed GPR registers.
142 * When the transaction is active, 'ckpt_regs' holds the checkpointed
143 * GPR register values for the current transaction to fall back on if it
144 * aborts in between. This function sets those checkpointed GPR registers.
145 * The userspace interface buffer layout is as follows.
148 * struct pt_regs ckpt_regs;
151 int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset,
152 unsigned int pos, unsigned int count,
153 const void *kbuf, const void __user *ubuf)
158 if (!cpu_has_feature(CPU_FTR_TM))
161 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
164 flush_tmregs_to_thread(target);
165 flush_fp_to_thread(target);
166 flush_altivec_to_thread(target);
168 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
169 &target->thread.ckpt_regs,
170 0, PT_MSR * sizeof(reg));
172 if (!ret && count > 0) {
173 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®,
174 PT_MSR * sizeof(reg),
175 (PT_MSR + 1) * sizeof(reg));
177 ret = set_user_ckpt_msr(target, reg);
180 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
181 offsetof(struct pt_regs, msr) + sizeof(long));
184 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
185 &target->thread.ckpt_regs.orig_gpr3,
186 PT_ORIG_R3 * sizeof(reg),
187 (PT_MAX_PUT_REG + 1) * sizeof(reg));
189 if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret)
190 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
191 (PT_MAX_PUT_REG + 1) * sizeof(reg),
192 PT_TRAP * sizeof(reg));
194 if (!ret && count > 0) {
195 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®,
196 PT_TRAP * sizeof(reg),
197 (PT_TRAP + 1) * sizeof(reg));
199 ret = set_user_ckpt_trap(target, reg);
203 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
204 (PT_TRAP + 1) * sizeof(reg), -1);
210 * tm_cfpr_active - get active number of registers in CFPR
211 * @target: The target task.
212 * @regset: The user regset structure.
214 * This function checks for the active number of available
215 * regisers in transaction checkpointed FPR category.
217 int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset)
219 if (!cpu_has_feature(CPU_FTR_TM))
222 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
229 * tm_cfpr_get - get CFPR registers
230 * @target: The target task.
231 * @regset: The user regset structure.
232 * @pos: The buffer position.
233 * @count: Number of bytes to copy.
234 * @kbuf: Kernel buffer to copy from.
235 * @ubuf: User buffer to copy into.
237 * This function gets in transaction checkpointed FPR registers.
239 * When the transaction is active 'ckfp_state' holds the checkpointed
240 * values for the current transaction to fall back on if it aborts
241 * in between. This function gets those checkpointed FPR registers.
242 * The userspace interface buffer layout is as follows.
249 int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
250 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
255 if (!cpu_has_feature(CPU_FTR_TM))
258 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
261 flush_tmregs_to_thread(target);
262 flush_fp_to_thread(target);
263 flush_altivec_to_thread(target);
265 /* copy to local buffer then write that out */
266 for (i = 0; i < 32 ; i++)
267 buf[i] = target->thread.TS_CKFPR(i);
268 buf[32] = target->thread.ckfp_state.fpscr;
269 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
273 * tm_cfpr_set - set CFPR registers
274 * @target: The target task.
275 * @regset: The user regset structure.
276 * @pos: The buffer position.
277 * @count: Number of bytes to copy.
278 * @kbuf: Kernel buffer to copy into.
279 * @ubuf: User buffer to copy from.
281 * This function sets in transaction checkpointed FPR registers.
283 * When the transaction is active 'ckfp_state' holds the checkpointed
284 * FPR register values for the current transaction to fall back on
285 * if it aborts in between. This function sets these checkpointed
286 * FPR registers. The userspace interface buffer layout is as follows.
293 int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset,
294 unsigned int pos, unsigned int count,
295 const void *kbuf, const void __user *ubuf)
300 if (!cpu_has_feature(CPU_FTR_TM))
303 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
306 flush_tmregs_to_thread(target);
307 flush_fp_to_thread(target);
308 flush_altivec_to_thread(target);
310 for (i = 0; i < 32; i++)
311 buf[i] = target->thread.TS_CKFPR(i);
312 buf[32] = target->thread.ckfp_state.fpscr;
314 /* copy to local buffer then write that out */
315 i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
318 for (i = 0; i < 32 ; i++)
319 target->thread.TS_CKFPR(i) = buf[i];
320 target->thread.ckfp_state.fpscr = buf[32];
325 * tm_cvmx_active - get active number of registers in CVMX
326 * @target: The target task.
327 * @regset: The user regset structure.
329 * This function checks for the active number of available
330 * regisers in checkpointed VMX category.
332 int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset)
334 if (!cpu_has_feature(CPU_FTR_TM))
337 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
344 * tm_cvmx_get - get CMVX registers
345 * @target: The target task.
346 * @regset: The user regset structure.
347 * @pos: The buffer position.
348 * @count: Number of bytes to copy.
349 * @kbuf: Kernel buffer to copy from.
350 * @ubuf: User buffer to copy into.
352 * This function gets in transaction checkpointed VMX registers.
354 * When the transaction is active 'ckvr_state' and 'ckvrsave' hold
355 * the checkpointed values for the current transaction to fall
356 * back on if it aborts in between. The userspace interface buffer
357 * layout is as follows.
365 int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
366 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
370 BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
372 if (!cpu_has_feature(CPU_FTR_TM))
375 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
378 /* Flush the state */
379 flush_tmregs_to_thread(target);
380 flush_fp_to_thread(target);
381 flush_altivec_to_thread(target);
383 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state,
384 0, 33 * sizeof(vector128));
387 * Copy out only the low-order word of vrsave.
393 memset(&vrsave, 0, sizeof(vrsave));
394 vrsave.word = target->thread.ckvrsave;
395 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
396 33 * sizeof(vector128), -1);
403 * tm_cvmx_set - set CMVX registers
404 * @target: The target task.
405 * @regset: The user regset structure.
406 * @pos: The buffer position.
407 * @count: Number of bytes to copy.
408 * @kbuf: Kernel buffer to copy into.
409 * @ubuf: User buffer to copy from.
411 * This function sets in transaction checkpointed VMX registers.
413 * When the transaction is active 'ckvr_state' and 'ckvrsave' hold
414 * the checkpointed values for the current transaction to fall
415 * back on if it aborts in between. The userspace interface buffer
416 * layout is as follows.
424 int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset,
425 unsigned int pos, unsigned int count,
426 const void *kbuf, const void __user *ubuf)
430 BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
432 if (!cpu_has_feature(CPU_FTR_TM))
435 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
438 flush_tmregs_to_thread(target);
439 flush_fp_to_thread(target);
440 flush_altivec_to_thread(target);
442 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state,
443 0, 33 * sizeof(vector128));
444 if (!ret && count > 0) {
446 * We use only the low-order word of vrsave.
452 memset(&vrsave, 0, sizeof(vrsave));
453 vrsave.word = target->thread.ckvrsave;
454 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
455 33 * sizeof(vector128), -1);
457 target->thread.ckvrsave = vrsave.word;
464 * tm_cvsx_active - get active number of registers in CVSX
465 * @target: The target task.
466 * @regset: The user regset structure.
468 * This function checks for the active number of available
469 * regisers in transaction checkpointed VSX category.
471 int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset)
473 if (!cpu_has_feature(CPU_FTR_TM))
476 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
479 flush_vsx_to_thread(target);
480 return target->thread.used_vsr ? regset->n : 0;
484 * tm_cvsx_get - get CVSX registers
485 * @target: The target task.
486 * @regset: The user regset structure.
487 * @pos: The buffer position.
488 * @count: Number of bytes to copy.
489 * @kbuf: Kernel buffer to copy from.
490 * @ubuf: User buffer to copy into.
492 * This function gets in transaction checkpointed VSX registers.
494 * When the transaction is active 'ckfp_state' holds the checkpointed
495 * values for the current transaction to fall back on if it aborts
496 * in between. This function gets those checkpointed VSX registers.
497 * The userspace interface buffer layout is as follows.
503 int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset,
504 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
509 if (!cpu_has_feature(CPU_FTR_TM))
512 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
515 /* Flush the state */
516 flush_tmregs_to_thread(target);
517 flush_fp_to_thread(target);
518 flush_altivec_to_thread(target);
519 flush_vsx_to_thread(target);
521 for (i = 0; i < 32 ; i++)
522 buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
523 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
524 buf, 0, 32 * sizeof(double));
530 * tm_cvsx_set - set CFPR registers
531 * @target: The target task.
532 * @regset: The user regset structure.
533 * @pos: The buffer position.
534 * @count: Number of bytes to copy.
535 * @kbuf: Kernel buffer to copy into.
536 * @ubuf: User buffer to copy from.
538 * This function sets in transaction checkpointed VSX registers.
540 * When the transaction is active 'ckfp_state' holds the checkpointed
541 * VSX register values for the current transaction to fall back on
542 * if it aborts in between. This function sets these checkpointed
543 * FPR registers. The userspace interface buffer layout is as follows.
549 int tm_cvsx_set(struct task_struct *target, const struct user_regset *regset,
550 unsigned int pos, unsigned int count,
551 const void *kbuf, const void __user *ubuf)
556 if (!cpu_has_feature(CPU_FTR_TM))
559 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
562 /* Flush the state */
563 flush_tmregs_to_thread(target);
564 flush_fp_to_thread(target);
565 flush_altivec_to_thread(target);
566 flush_vsx_to_thread(target);
568 for (i = 0; i < 32 ; i++)
569 buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
571 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
572 buf, 0, 32 * sizeof(double));
574 for (i = 0; i < 32 ; i++)
575 target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
581 * tm_spr_active - get active number of registers in TM SPR
582 * @target: The target task.
583 * @regset: The user regset structure.
585 * This function checks the active number of available
586 * regisers in the transactional memory SPR category.
588 int tm_spr_active(struct task_struct *target, const struct user_regset *regset)
590 if (!cpu_has_feature(CPU_FTR_TM))
597 * tm_spr_get - get the TM related SPR registers
598 * @target: The target task.
599 * @regset: The user regset structure.
600 * @pos: The buffer position.
601 * @count: Number of bytes to copy.
602 * @kbuf: Kernel buffer to copy from.
603 * @ubuf: User buffer to copy into.
605 * This function gets transactional memory related SPR registers.
606 * The userspace interface buffer layout is as follows.
614 int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
615 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
620 BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
621 BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
622 BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs));
624 if (!cpu_has_feature(CPU_FTR_TM))
627 /* Flush the states */
628 flush_tmregs_to_thread(target);
629 flush_fp_to_thread(target);
630 flush_altivec_to_thread(target);
633 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
634 &target->thread.tm_tfhar, 0, sizeof(u64));
636 /* TEXASR register */
638 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
639 &target->thread.tm_texasr, sizeof(u64),
644 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
645 &target->thread.tm_tfiar,
646 2 * sizeof(u64), 3 * sizeof(u64));
651 * tm_spr_set - set the TM related SPR registers
652 * @target: The target task.
653 * @regset: The user regset structure.
654 * @pos: The buffer position.
655 * @count: Number of bytes to copy.
656 * @kbuf: Kernel buffer to copy into.
657 * @ubuf: User buffer to copy from.
659 * This function sets transactional memory related SPR registers.
660 * The userspace interface buffer layout is as follows.
668 int tm_spr_set(struct task_struct *target, const struct user_regset *regset,
669 unsigned int pos, unsigned int count,
670 const void *kbuf, const void __user *ubuf)
675 BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
676 BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
677 BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs));
679 if (!cpu_has_feature(CPU_FTR_TM))
682 /* Flush the states */
683 flush_tmregs_to_thread(target);
684 flush_fp_to_thread(target);
685 flush_altivec_to_thread(target);
688 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
689 &target->thread.tm_tfhar, 0, sizeof(u64));
691 /* TEXASR register */
693 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
694 &target->thread.tm_texasr, sizeof(u64),
699 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
700 &target->thread.tm_tfiar,
701 2 * sizeof(u64), 3 * sizeof(u64));
705 int tm_tar_active(struct task_struct *target, const struct user_regset *regset)
707 if (!cpu_has_feature(CPU_FTR_TM))
710 if (MSR_TM_ACTIVE(target->thread.regs->msr))
716 int tm_tar_get(struct task_struct *target, const struct user_regset *regset,
717 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
721 if (!cpu_has_feature(CPU_FTR_TM))
724 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
727 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
728 &target->thread.tm_tar, 0, sizeof(u64));
732 int tm_tar_set(struct task_struct *target, const struct user_regset *regset,
733 unsigned int pos, unsigned int count,
734 const void *kbuf, const void __user *ubuf)
738 if (!cpu_has_feature(CPU_FTR_TM))
741 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
744 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
745 &target->thread.tm_tar, 0, sizeof(u64));
749 int tm_ppr_active(struct task_struct *target, const struct user_regset *regset)
751 if (!cpu_has_feature(CPU_FTR_TM))
754 if (MSR_TM_ACTIVE(target->thread.regs->msr))
761 int tm_ppr_get(struct task_struct *target, const struct user_regset *regset,
762 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
766 if (!cpu_has_feature(CPU_FTR_TM))
769 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
772 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
773 &target->thread.tm_ppr, 0, sizeof(u64));
777 int tm_ppr_set(struct task_struct *target, const struct user_regset *regset,
778 unsigned int pos, unsigned int count,
779 const void *kbuf, const void __user *ubuf)
783 if (!cpu_has_feature(CPU_FTR_TM))
786 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
789 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
790 &target->thread.tm_ppr, 0, sizeof(u64));
794 int tm_dscr_active(struct task_struct *target, const struct user_regset *regset)
796 if (!cpu_has_feature(CPU_FTR_TM))
799 if (MSR_TM_ACTIVE(target->thread.regs->msr))
805 int tm_dscr_get(struct task_struct *target, const struct user_regset *regset,
806 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
810 if (!cpu_has_feature(CPU_FTR_TM))
813 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
816 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
817 &target->thread.tm_dscr, 0, sizeof(u64));
821 int tm_dscr_set(struct task_struct *target, const struct user_regset *regset,
822 unsigned int pos, unsigned int count,
823 const void *kbuf, const void __user *ubuf)
827 if (!cpu_has_feature(CPU_FTR_TM))
830 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
833 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
834 &target->thread.tm_dscr, 0, sizeof(u64));
838 int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset,
839 unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
841 return gpr32_get_common(target, regset, pos, count, kbuf, ubuf,
842 &target->thread.ckpt_regs.gpr[0]);
845 int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset,
846 unsigned int pos, unsigned int count,
847 const void *kbuf, const void __user *ubuf)
849 return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
850 &target->thread.ckpt_regs.gpr[0]);