cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ptrace-tm.c (20634B)


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