1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 #include <linux/regset.h>
4
5 #include <asm/switch_to.h>
6 #include <asm/tm.h>
7 #include <asm/asm-prototypes.h>
8
9 #include "ptrace-decl.h"
10
flush_tmregs_to_thread(struct task_struct * tsk)11 void flush_tmregs_to_thread(struct task_struct *tsk)
12 {
13 /*
14 * If task is not current, it will have been flushed already to
15 * it's thread_struct during __switch_to().
16 *
17 * A reclaim flushes ALL the state or if not in TM save TM SPRs
18 * in the appropriate thread structures from live.
19 */
20
21 if (!cpu_has_feature(CPU_FTR_TM) || tsk != current)
22 return;
23
24 if (MSR_TM_SUSPENDED(mfmsr())) {
25 tm_reclaim_current(TM_CAUSE_SIGNAL);
26 } else {
27 tm_enable();
28 tm_save_sprs(&tsk->thread);
29 }
30 }
31
get_user_ckpt_msr(struct task_struct * task)32 static unsigned long get_user_ckpt_msr(struct task_struct *task)
33 {
34 return task->thread.ckpt_regs.msr | task->thread.fpexc_mode;
35 }
36
set_user_ckpt_msr(struct task_struct * task,unsigned long msr)37 static int set_user_ckpt_msr(struct task_struct *task, unsigned long msr)
38 {
39 task->thread.ckpt_regs.msr &= ~MSR_DEBUGCHANGE;
40 task->thread.ckpt_regs.msr |= msr & MSR_DEBUGCHANGE;
41 return 0;
42 }
43
set_user_ckpt_trap(struct task_struct * task,unsigned long trap)44 static int set_user_ckpt_trap(struct task_struct *task, unsigned long trap)
45 {
46 set_trap(&task->thread.ckpt_regs, trap);
47 return 0;
48 }
49
50 /**
51 * tm_cgpr_active - get active number of registers in CGPR
52 * @target: The target task.
53 * @regset: The user regset structure.
54 *
55 * This function checks for the active number of available
56 * regisers in transaction checkpointed GPR category.
57 */
tm_cgpr_active(struct task_struct * target,const struct user_regset * regset)58 int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset)
59 {
60 if (!cpu_has_feature(CPU_FTR_TM))
61 return -ENODEV;
62
63 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
64 return 0;
65
66 return regset->n;
67 }
68
69 /**
70 * tm_cgpr_get - get CGPR registers
71 * @target: The target task.
72 * @regset: The user regset structure.
73 * @to: Destination of copy.
74 *
75 * This function gets transaction checkpointed GPR registers.
76 *
77 * When the transaction is active, 'ckpt_regs' holds all the checkpointed
78 * GPR register values for the current transaction to fall back on if it
79 * aborts in between. This function gets those checkpointed GPR registers.
80 * The userspace interface buffer layout is as follows.
81 *
82 * struct data {
83 * struct pt_regs ckpt_regs;
84 * };
85 */
tm_cgpr_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)86 int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
87 struct membuf to)
88 {
89 if (!cpu_has_feature(CPU_FTR_TM))
90 return -ENODEV;
91
92 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
93 return -ENODATA;
94
95 flush_tmregs_to_thread(target);
96 flush_fp_to_thread(target);
97 flush_altivec_to_thread(target);
98
99 membuf_write(&to, &target->thread.ckpt_regs,
100 offsetof(struct pt_regs, msr));
101 membuf_store(&to, get_user_ckpt_msr(target));
102
103 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
104 offsetof(struct pt_regs, msr) + sizeof(long));
105
106 membuf_write(&to, &target->thread.ckpt_regs.orig_gpr3,
107 sizeof(struct user_pt_regs) -
108 offsetof(struct pt_regs, orig_gpr3));
109 return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) -
110 sizeof(struct user_pt_regs));
111 }
112
113 /*
114 * tm_cgpr_set - set the CGPR registers
115 * @target: The target task.
116 * @regset: The user regset structure.
117 * @pos: The buffer position.
118 * @count: Number of bytes to copy.
119 * @kbuf: Kernel buffer to copy into.
120 * @ubuf: User buffer to copy from.
121 *
122 * This function sets in transaction checkpointed GPR registers.
123 *
124 * When the transaction is active, 'ckpt_regs' holds the checkpointed
125 * GPR register values for the current transaction to fall back on if it
126 * aborts in between. This function sets those checkpointed GPR registers.
127 * The userspace interface buffer layout is as follows.
128 *
129 * struct data {
130 * struct pt_regs ckpt_regs;
131 * };
132 */
tm_cgpr_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)133 int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset,
134 unsigned int pos, unsigned int count,
135 const void *kbuf, const void __user *ubuf)
136 {
137 unsigned long reg;
138 int ret;
139
140 if (!cpu_has_feature(CPU_FTR_TM))
141 return -ENODEV;
142
143 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
144 return -ENODATA;
145
146 flush_tmregs_to_thread(target);
147 flush_fp_to_thread(target);
148 flush_altivec_to_thread(target);
149
150 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
151 &target->thread.ckpt_regs,
152 0, PT_MSR * sizeof(reg));
153
154 if (!ret && count > 0) {
155 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®,
156 PT_MSR * sizeof(reg),
157 (PT_MSR + 1) * sizeof(reg));
158 if (!ret)
159 ret = set_user_ckpt_msr(target, reg);
160 }
161
162 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
163 offsetof(struct pt_regs, msr) + sizeof(long));
164
165 if (!ret)
166 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
167 &target->thread.ckpt_regs.orig_gpr3,
168 PT_ORIG_R3 * sizeof(reg),
169 (PT_MAX_PUT_REG + 1) * sizeof(reg));
170
171 if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret)
172 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
173 (PT_MAX_PUT_REG + 1) * sizeof(reg),
174 PT_TRAP * sizeof(reg));
175
176 if (!ret && count > 0) {
177 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®,
178 PT_TRAP * sizeof(reg),
179 (PT_TRAP + 1) * sizeof(reg));
180 if (!ret)
181 ret = set_user_ckpt_trap(target, reg);
182 }
183
184 if (!ret)
185 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
186 (PT_TRAP + 1) * sizeof(reg), -1);
187
188 return ret;
189 }
190
191 /**
192 * tm_cfpr_active - get active number of registers in CFPR
193 * @target: The target task.
194 * @regset: The user regset structure.
195 *
196 * This function checks for the active number of available
197 * regisers in transaction checkpointed FPR category.
198 */
tm_cfpr_active(struct task_struct * target,const struct user_regset * regset)199 int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset)
200 {
201 if (!cpu_has_feature(CPU_FTR_TM))
202 return -ENODEV;
203
204 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
205 return 0;
206
207 return regset->n;
208 }
209
210 /**
211 * tm_cfpr_get - get CFPR registers
212 * @target: The target task.
213 * @regset: The user regset structure.
214 * @to: Destination of copy.
215 *
216 * This function gets in transaction checkpointed FPR registers.
217 *
218 * When the transaction is active 'ckfp_state' holds the checkpointed
219 * values for the current transaction to fall back on if it aborts
220 * in between. This function gets those checkpointed FPR registers.
221 * The userspace interface buffer layout is as follows.
222 *
223 * struct data {
224 * u64 fpr[32];
225 * u64 fpscr;
226 *};
227 */
tm_cfpr_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)228 int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
229 struct membuf to)
230 {
231 u64 buf[33];
232 int i;
233
234 if (!cpu_has_feature(CPU_FTR_TM))
235 return -ENODEV;
236
237 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
238 return -ENODATA;
239
240 flush_tmregs_to_thread(target);
241 flush_fp_to_thread(target);
242 flush_altivec_to_thread(target);
243
244 /* copy to local buffer then write that out */
245 for (i = 0; i < 32 ; i++)
246 buf[i] = target->thread.TS_CKFPR(i);
247 buf[32] = target->thread.ckfp_state.fpscr;
248 return membuf_write(&to, buf, sizeof(buf));
249 }
250
251 /**
252 * tm_cfpr_set - set CFPR registers
253 * @target: The target task.
254 * @regset: The user regset structure.
255 * @pos: The buffer position.
256 * @count: Number of bytes to copy.
257 * @kbuf: Kernel buffer to copy into.
258 * @ubuf: User buffer to copy from.
259 *
260 * This function sets in transaction checkpointed FPR registers.
261 *
262 * When the transaction is active 'ckfp_state' holds the checkpointed
263 * FPR register values for the current transaction to fall back on
264 * if it aborts in between. This function sets these checkpointed
265 * FPR registers. The userspace interface buffer layout is as follows.
266 *
267 * struct data {
268 * u64 fpr[32];
269 * u64 fpscr;
270 *};
271 */
tm_cfpr_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)272 int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset,
273 unsigned int pos, unsigned int count,
274 const void *kbuf, const void __user *ubuf)
275 {
276 u64 buf[33];
277 int i;
278
279 if (!cpu_has_feature(CPU_FTR_TM))
280 return -ENODEV;
281
282 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
283 return -ENODATA;
284
285 flush_tmregs_to_thread(target);
286 flush_fp_to_thread(target);
287 flush_altivec_to_thread(target);
288
289 for (i = 0; i < 32; i++)
290 buf[i] = target->thread.TS_CKFPR(i);
291 buf[32] = target->thread.ckfp_state.fpscr;
292
293 /* copy to local buffer then write that out */
294 i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
295 if (i)
296 return i;
297 for (i = 0; i < 32 ; i++)
298 target->thread.TS_CKFPR(i) = buf[i];
299 target->thread.ckfp_state.fpscr = buf[32];
300 return 0;
301 }
302
303 /**
304 * tm_cvmx_active - get active number of registers in CVMX
305 * @target: The target task.
306 * @regset: The user regset structure.
307 *
308 * This function checks for the active number of available
309 * regisers in checkpointed VMX category.
310 */
tm_cvmx_active(struct task_struct * target,const struct user_regset * regset)311 int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset)
312 {
313 if (!cpu_has_feature(CPU_FTR_TM))
314 return -ENODEV;
315
316 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
317 return 0;
318
319 return regset->n;
320 }
321
322 /**
323 * tm_cvmx_get - get CMVX registers
324 * @target: The target task.
325 * @regset: The user regset structure.
326 * @to: Destination of copy.
327 *
328 * This function gets in transaction checkpointed VMX registers.
329 *
330 * When the transaction is active 'ckvr_state' and 'ckvrsave' hold
331 * the checkpointed values for the current transaction to fall
332 * back on if it aborts in between. The userspace interface buffer
333 * layout is as follows.
334 *
335 * struct data {
336 * vector128 vr[32];
337 * vector128 vscr;
338 * vector128 vrsave;
339 *};
340 */
tm_cvmx_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)341 int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
342 struct membuf to)
343 {
344 union {
345 elf_vrreg_t reg;
346 u32 word;
347 } vrsave;
348 BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
349
350 if (!cpu_has_feature(CPU_FTR_TM))
351 return -ENODEV;
352
353 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
354 return -ENODATA;
355
356 /* Flush the state */
357 flush_tmregs_to_thread(target);
358 flush_fp_to_thread(target);
359 flush_altivec_to_thread(target);
360
361 membuf_write(&to, &target->thread.ckvr_state, 33 * sizeof(vector128));
362 /*
363 * Copy out only the low-order word of vrsave.
364 */
365 memset(&vrsave, 0, sizeof(vrsave));
366 vrsave.word = target->thread.ckvrsave;
367 return membuf_write(&to, &vrsave, sizeof(vrsave));
368 }
369
370 /**
371 * tm_cvmx_set - set CMVX registers
372 * @target: The target task.
373 * @regset: The user regset structure.
374 * @pos: The buffer position.
375 * @count: Number of bytes to copy.
376 * @kbuf: Kernel buffer to copy into.
377 * @ubuf: User buffer to copy from.
378 *
379 * This function sets in transaction checkpointed VMX registers.
380 *
381 * When the transaction is active 'ckvr_state' and 'ckvrsave' hold
382 * the checkpointed values for the current transaction to fall
383 * back on if it aborts in between. The userspace interface buffer
384 * layout is as follows.
385 *
386 * struct data {
387 * vector128 vr[32];
388 * vector128 vscr;
389 * vector128 vrsave;
390 *};
391 */
tm_cvmx_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)392 int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset,
393 unsigned int pos, unsigned int count,
394 const void *kbuf, const void __user *ubuf)
395 {
396 int ret;
397
398 BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
399
400 if (!cpu_has_feature(CPU_FTR_TM))
401 return -ENODEV;
402
403 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
404 return -ENODATA;
405
406 flush_tmregs_to_thread(target);
407 flush_fp_to_thread(target);
408 flush_altivec_to_thread(target);
409
410 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state,
411 0, 33 * sizeof(vector128));
412 if (!ret && count > 0) {
413 /*
414 * We use only the low-order word of vrsave.
415 */
416 union {
417 elf_vrreg_t reg;
418 u32 word;
419 } vrsave;
420 memset(&vrsave, 0, sizeof(vrsave));
421 vrsave.word = target->thread.ckvrsave;
422 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
423 33 * sizeof(vector128), -1);
424 if (!ret)
425 target->thread.ckvrsave = vrsave.word;
426 }
427
428 return ret;
429 }
430
431 /**
432 * tm_cvsx_active - get active number of registers in CVSX
433 * @target: The target task.
434 * @regset: The user regset structure.
435 *
436 * This function checks for the active number of available
437 * regisers in transaction checkpointed VSX category.
438 */
tm_cvsx_active(struct task_struct * target,const struct user_regset * regset)439 int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset)
440 {
441 if (!cpu_has_feature(CPU_FTR_TM))
442 return -ENODEV;
443
444 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
445 return 0;
446
447 flush_vsx_to_thread(target);
448 return target->thread.used_vsr ? regset->n : 0;
449 }
450
451 /**
452 * tm_cvsx_get - get CVSX registers
453 * @target: The target task.
454 * @regset: The user regset structure.
455 * @to: Destination of copy.
456 *
457 * This function gets in transaction checkpointed VSX registers.
458 *
459 * When the transaction is active 'ckfp_state' holds the checkpointed
460 * values for the current transaction to fall back on if it aborts
461 * in between. This function gets those checkpointed VSX registers.
462 * The userspace interface buffer layout is as follows.
463 *
464 * struct data {
465 * u64 vsx[32];
466 *};
467 */
tm_cvsx_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)468 int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset,
469 struct membuf to)
470 {
471 u64 buf[32];
472 int i;
473
474 if (!cpu_has_feature(CPU_FTR_TM))
475 return -ENODEV;
476
477 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
478 return -ENODATA;
479
480 /* Flush the state */
481 flush_tmregs_to_thread(target);
482 flush_fp_to_thread(target);
483 flush_altivec_to_thread(target);
484 flush_vsx_to_thread(target);
485
486 for (i = 0; i < 32 ; i++)
487 buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
488 return membuf_write(&to, buf, 32 * sizeof(double));
489 }
490
491 /**
492 * tm_cvsx_set - set CFPR registers
493 * @target: The target task.
494 * @regset: The user regset structure.
495 * @pos: The buffer position.
496 * @count: Number of bytes to copy.
497 * @kbuf: Kernel buffer to copy into.
498 * @ubuf: User buffer to copy from.
499 *
500 * This function sets in transaction checkpointed VSX registers.
501 *
502 * When the transaction is active 'ckfp_state' holds the checkpointed
503 * VSX register values for the current transaction to fall back on
504 * if it aborts in between. This function sets these checkpointed
505 * FPR registers. The userspace interface buffer layout is as follows.
506 *
507 * struct data {
508 * u64 vsx[32];
509 *};
510 */
tm_cvsx_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)511 int tm_cvsx_set(struct task_struct *target, const struct user_regset *regset,
512 unsigned int pos, unsigned int count,
513 const void *kbuf, const void __user *ubuf)
514 {
515 u64 buf[32];
516 int ret, i;
517
518 if (!cpu_has_feature(CPU_FTR_TM))
519 return -ENODEV;
520
521 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
522 return -ENODATA;
523
524 /* Flush the state */
525 flush_tmregs_to_thread(target);
526 flush_fp_to_thread(target);
527 flush_altivec_to_thread(target);
528 flush_vsx_to_thread(target);
529
530 for (i = 0; i < 32 ; i++)
531 buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
532
533 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
534 buf, 0, 32 * sizeof(double));
535 if (!ret)
536 for (i = 0; i < 32 ; i++)
537 target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
538
539 return ret;
540 }
541
542 /**
543 * tm_spr_active - get active number of registers in TM SPR
544 * @target: The target task.
545 * @regset: The user regset structure.
546 *
547 * This function checks the active number of available
548 * regisers in the transactional memory SPR category.
549 */
tm_spr_active(struct task_struct * target,const struct user_regset * regset)550 int tm_spr_active(struct task_struct *target, const struct user_regset *regset)
551 {
552 if (!cpu_has_feature(CPU_FTR_TM))
553 return -ENODEV;
554
555 return regset->n;
556 }
557
558 /**
559 * tm_spr_get - get the TM related SPR registers
560 * @target: The target task.
561 * @regset: The user regset structure.
562 * @to: Destination of copy.
563 *
564 * This function gets transactional memory related SPR registers.
565 * The userspace interface buffer layout is as follows.
566 *
567 * struct {
568 * u64 tm_tfhar;
569 * u64 tm_texasr;
570 * u64 tm_tfiar;
571 * };
572 */
tm_spr_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)573 int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
574 struct membuf to)
575 {
576 /* Build tests */
577 BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
578 BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
579 BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs));
580
581 if (!cpu_has_feature(CPU_FTR_TM))
582 return -ENODEV;
583
584 /* Flush the states */
585 flush_tmregs_to_thread(target);
586 flush_fp_to_thread(target);
587 flush_altivec_to_thread(target);
588
589 /* TFHAR register */
590 membuf_write(&to, &target->thread.tm_tfhar, sizeof(u64));
591 /* TEXASR register */
592 membuf_write(&to, &target->thread.tm_texasr, sizeof(u64));
593 /* TFIAR register */
594 return membuf_write(&to, &target->thread.tm_tfiar, sizeof(u64));
595 }
596
597 /**
598 * tm_spr_set - set the TM related SPR registers
599 * @target: The target task.
600 * @regset: The user regset structure.
601 * @pos: The buffer position.
602 * @count: Number of bytes to copy.
603 * @kbuf: Kernel buffer to copy into.
604 * @ubuf: User buffer to copy from.
605 *
606 * This function sets transactional memory related SPR registers.
607 * The userspace interface buffer layout is as follows.
608 *
609 * struct {
610 * u64 tm_tfhar;
611 * u64 tm_texasr;
612 * u64 tm_tfiar;
613 * };
614 */
tm_spr_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)615 int tm_spr_set(struct task_struct *target, const struct user_regset *regset,
616 unsigned int pos, unsigned int count,
617 const void *kbuf, const void __user *ubuf)
618 {
619 int ret;
620
621 /* Build tests */
622 BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
623 BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
624 BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs));
625
626 if (!cpu_has_feature(CPU_FTR_TM))
627 return -ENODEV;
628
629 /* Flush the states */
630 flush_tmregs_to_thread(target);
631 flush_fp_to_thread(target);
632 flush_altivec_to_thread(target);
633
634 /* TFHAR register */
635 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
636 &target->thread.tm_tfhar, 0, sizeof(u64));
637
638 /* TEXASR register */
639 if (!ret)
640 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
641 &target->thread.tm_texasr, sizeof(u64),
642 2 * sizeof(u64));
643
644 /* TFIAR register */
645 if (!ret)
646 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
647 &target->thread.tm_tfiar,
648 2 * sizeof(u64), 3 * sizeof(u64));
649 return ret;
650 }
651
tm_tar_active(struct task_struct * target,const struct user_regset * regset)652 int tm_tar_active(struct task_struct *target, const struct user_regset *regset)
653 {
654 if (!cpu_has_feature(CPU_FTR_TM))
655 return -ENODEV;
656
657 if (MSR_TM_ACTIVE(target->thread.regs->msr))
658 return regset->n;
659
660 return 0;
661 }
662
tm_tar_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)663 int tm_tar_get(struct task_struct *target, const struct user_regset *regset,
664 struct membuf to)
665 {
666 if (!cpu_has_feature(CPU_FTR_TM))
667 return -ENODEV;
668
669 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
670 return -ENODATA;
671
672 return membuf_write(&to, &target->thread.tm_tar, sizeof(u64));
673 }
674
tm_tar_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)675 int tm_tar_set(struct task_struct *target, const struct user_regset *regset,
676 unsigned int pos, unsigned int count,
677 const void *kbuf, const void __user *ubuf)
678 {
679 int ret;
680
681 if (!cpu_has_feature(CPU_FTR_TM))
682 return -ENODEV;
683
684 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
685 return -ENODATA;
686
687 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
688 &target->thread.tm_tar, 0, sizeof(u64));
689 return ret;
690 }
691
tm_ppr_active(struct task_struct * target,const struct user_regset * regset)692 int tm_ppr_active(struct task_struct *target, const struct user_regset *regset)
693 {
694 if (!cpu_has_feature(CPU_FTR_TM))
695 return -ENODEV;
696
697 if (MSR_TM_ACTIVE(target->thread.regs->msr))
698 return regset->n;
699
700 return 0;
701 }
702
703
tm_ppr_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)704 int tm_ppr_get(struct task_struct *target, const struct user_regset *regset,
705 struct membuf to)
706 {
707 if (!cpu_has_feature(CPU_FTR_TM))
708 return -ENODEV;
709
710 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
711 return -ENODATA;
712
713 return membuf_write(&to, &target->thread.tm_ppr, sizeof(u64));
714 }
715
tm_ppr_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)716 int tm_ppr_set(struct task_struct *target, const struct user_regset *regset,
717 unsigned int pos, unsigned int count,
718 const void *kbuf, const void __user *ubuf)
719 {
720 int ret;
721
722 if (!cpu_has_feature(CPU_FTR_TM))
723 return -ENODEV;
724
725 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
726 return -ENODATA;
727
728 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
729 &target->thread.tm_ppr, 0, sizeof(u64));
730 return ret;
731 }
732
tm_dscr_active(struct task_struct * target,const struct user_regset * regset)733 int tm_dscr_active(struct task_struct *target, const struct user_regset *regset)
734 {
735 if (!cpu_has_feature(CPU_FTR_TM))
736 return -ENODEV;
737
738 if (MSR_TM_ACTIVE(target->thread.regs->msr))
739 return regset->n;
740
741 return 0;
742 }
743
tm_dscr_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)744 int tm_dscr_get(struct task_struct *target, const struct user_regset *regset,
745 struct membuf to)
746 {
747 if (!cpu_has_feature(CPU_FTR_TM))
748 return -ENODEV;
749
750 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
751 return -ENODATA;
752
753 return membuf_write(&to, &target->thread.tm_dscr, sizeof(u64));
754 }
755
tm_dscr_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)756 int tm_dscr_set(struct task_struct *target, const struct user_regset *regset,
757 unsigned int pos, unsigned int count,
758 const void *kbuf, const void __user *ubuf)
759 {
760 int ret;
761
762 if (!cpu_has_feature(CPU_FTR_TM))
763 return -ENODEV;
764
765 if (!MSR_TM_ACTIVE(target->thread.regs->msr))
766 return -ENODATA;
767
768 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
769 &target->thread.tm_dscr, 0, sizeof(u64));
770 return ret;
771 }
772
tm_cgpr32_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)773 int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset,
774 struct membuf to)
775 {
776 gpr32_get_common(target, regset, to,
777 &target->thread.ckpt_regs.gpr[0]);
778 return membuf_zero(&to, ELF_NGREG * sizeof(u32));
779 }
780
tm_cgpr32_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)781 int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset,
782 unsigned int pos, unsigned int count,
783 const void *kbuf, const void __user *ubuf)
784 {
785 return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
786 &target->thread.ckpt_regs.gpr[0]);
787 }
788