Commit 47e12855 authored by Al Viro's avatar Al Viro
Browse files

powerpc: switch to ->regset_get()



Note: compat variant of REGSET_TM_CGPR is almost certainly wrong;
it claims to be 48*64bit, but just as compat REGSET_GPR it stores
44*32bit of (truncated) registers + 4 32bit zeros... followed by
48 more 32bit zeroes.  Might be too late to change - it's a userland
ABI, after all ;-/

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 0557d64d
Loading
Loading
Loading
Loading
+12 −25
Original line number Diff line number Diff line
@@ -41,38 +41,25 @@ int vr_active(struct task_struct *target, const struct user_regset *regset)
 * };
 */
int vr_get(struct task_struct *target, const struct user_regset *regset,
	   unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
	   struct membuf to)
{
	int ret;
	union {
		elf_vrreg_t reg;
		u32 word;
	} vrsave;

	flush_altivec_to_thread(target);

	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
		     offsetof(struct thread_vr_state, vr[32]));

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  &target->thread.vr_state, 0,
				  33 * sizeof(vector128));
	if (!ret) {
	membuf_write(&to, &target->thread.vr_state, 33 * sizeof(vector128));
	/*
	 * Copy out only the low-order word of vrsave.
	 */
		int start, end;
		union {
			elf_vrreg_t reg;
			u32 word;
		} vrsave;
	memset(&vrsave, 0, sizeof(vrsave));

	vrsave.word = target->thread.vrsave;

		start = 33 * sizeof(vector128);
		end = start + sizeof(vrsave);
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
					  start, end);
	}

	return ret;
	return membuf_write(&to, &vrsave, sizeof(vrsave));
}

/*
+15 −29
Original line number Diff line number Diff line
@@ -63,8 +63,7 @@ enum powerpc_regset {

/* ptrace-(no)vsx */

int fpr_get(struct task_struct *target, const struct user_regset *regset,
	    unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn fpr_get;
int fpr_set(struct task_struct *target, const struct user_regset *regset,
	    unsigned int pos, unsigned int count,
	    const void *kbuf, const void __user *ubuf);
@@ -72,8 +71,7 @@ int fpr_set(struct task_struct *target, const struct user_regset *regset,
/* ptrace-vsx */

int vsr_active(struct task_struct *target, const struct user_regset *regset);
int vsr_get(struct task_struct *target, const struct user_regset *regset,
	    unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn vsr_get;
int vsr_set(struct task_struct *target, const struct user_regset *regset,
	    unsigned int pos, unsigned int count,
	    const void *kbuf, const void __user *ubuf);
@@ -81,8 +79,7 @@ int vsr_set(struct task_struct *target, const struct user_regset *regset,
/* ptrace-altivec */

int vr_active(struct task_struct *target, const struct user_regset *regset);
int vr_get(struct task_struct *target, const struct user_regset *regset,
	   unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn vr_get;
int vr_set(struct task_struct *target, const struct user_regset *regset,
	   unsigned int pos, unsigned int count,
	   const void *kbuf, const void __user *ubuf);
@@ -90,8 +87,7 @@ int vr_set(struct task_struct *target, const struct user_regset *regset,
/* ptrace-spe */

int evr_active(struct task_struct *target, const struct user_regset *regset);
int evr_get(struct task_struct *target, const struct user_regset *regset,
	    unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn evr_get;
int evr_set(struct task_struct *target, const struct user_regset *regset,
	    unsigned int pos, unsigned int count,
	    const void *kbuf, const void __user *ubuf);
@@ -100,8 +96,7 @@ int evr_set(struct task_struct *target, const struct user_regset *regset,

int gpr32_get_common(struct task_struct *target,
		     const struct user_regset *regset,
		     unsigned int pos, unsigned int count,
			    void *kbuf, void __user *ubuf,
		     struct membuf to,
		     unsigned long *regs);
int gpr32_set_common(struct task_struct *target,
		     const struct user_regset *regset,
@@ -118,55 +113,46 @@ static inline void flush_tmregs_to_thread(struct task_struct *tsk) { }
#endif

int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset);
int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_cgpr_get;
int 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);
int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset);
int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_cfpr_get;
int 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);
int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset);
int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_cvmx_get;
int 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);
int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset);
int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_cvsx_get;
int 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);
int tm_spr_active(struct task_struct *target, const struct user_regset *regset);
int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
	       unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_spr_get;
int 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);
int tm_tar_active(struct task_struct *target, const struct user_regset *regset);
int tm_tar_get(struct task_struct *target, const struct user_regset *regset,
	       unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_tar_get;
int 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);
int tm_ppr_active(struct task_struct *target, const struct user_regset *regset);
int tm_ppr_get(struct task_struct *target, const struct user_regset *regset,
	       unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_ppr_get;
int 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);
int tm_dscr_active(struct task_struct *target, const struct user_regset *regset);
int tm_dscr_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_dscr_get;
int 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);
int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset,
		  unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
user_regset_get2_fn tm_cgpr32_get;
int 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);
+2 −3
Original line number Diff line number Diff line
@@ -19,15 +19,14 @@
 * };
 */
int fpr_get(struct task_struct *target, const struct user_regset *regset,
	    unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
	    struct membuf to)
{
	BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
		     offsetof(struct thread_fp_state, fpr[32]));

	flush_fp_to_thread(target);

	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				   &target->thread.fp_state, 0, -1);
	return membuf_write(&to, &target->thread.fp_state, 33 * sizeof(u64));
}

/*
+4 −12
Original line number Diff line number Diff line
@@ -23,25 +23,17 @@ int evr_active(struct task_struct *target, const struct user_regset *regset)
}

int evr_get(struct task_struct *target, const struct user_regset *regset,
	    unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
	    struct membuf to)
{
	int ret;

	flush_spe_to_thread(target);

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  &target->thread.evr,
				  0, sizeof(target->thread.evr));
	membuf_write(&to, &target->thread.evr, sizeof(target->thread.evr));

	BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) !=
		     offsetof(struct thread_struct, spefscr));

	if (!ret)
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  &target->thread.acc,
					  sizeof(target->thread.evr), -1);

	return ret;
	return membuf_write(&to, &target->thread.acc,
				sizeof(u64) + sizeof(u32));
}

int evr_set(struct task_struct *target, const struct user_regset *regset,
+44 −108
Original line number Diff line number Diff line
@@ -70,10 +70,7 @@ int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset)
 * tm_cgpr_get - get CGPR registers
 * @target:	The target task.
 * @regset:	The user regset structure.
 * @pos:	The buffer position.
 * @count:	Number of bytes to copy.
 * @kbuf:	Kernel buffer to copy from.
 * @ubuf:	User buffer to copy into.
 * @to:		Destination of copy.
 *
 * This function gets transaction checkpointed GPR registers.
 *
@@ -87,10 +84,8 @@ int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset)
 * };
 */
int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
		struct membuf to)
{
	int ret;

	if (!cpu_has_feature(CPU_FTR_TM))
		return -ENODEV;

@@ -101,31 +96,18 @@ int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
	flush_fp_to_thread(target);
	flush_altivec_to_thread(target);

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  &target->thread.ckpt_regs,
				  0, offsetof(struct pt_regs, msr));
	if (!ret) {
		unsigned long msr = get_user_ckpt_msr(target);

		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr,
					  offsetof(struct pt_regs, msr),
					  offsetof(struct pt_regs, msr) +
					  sizeof(msr));
	}
	membuf_write(&to, &target->thread.ckpt_regs,
			offsetof(struct pt_regs, msr));
	membuf_store(&to, get_user_ckpt_msr(target));

	BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
		     offsetof(struct pt_regs, msr) + sizeof(long));

	if (!ret)
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  &target->thread.ckpt_regs.orig_gpr3,
					  offsetof(struct pt_regs, orig_gpr3),
	membuf_write(&to, &target->thread.ckpt_regs.orig_gpr3,
			sizeof(struct user_pt_regs) -
			offsetof(struct pt_regs, orig_gpr3));
	return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) -
			sizeof(struct user_pt_regs));
	if (!ret)
		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
					       sizeof(struct user_pt_regs), -1);

	return ret;
}

/*
@@ -229,10 +211,7 @@ int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset)
 * tm_cfpr_get - get CFPR registers
 * @target:	The target task.
 * @regset:	The user regset structure.
 * @pos:	The buffer position.
 * @count:	Number of bytes to copy.
 * @kbuf:	Kernel buffer to copy from.
 * @ubuf:	User buffer to copy into.
 * @to:		Destination of copy.
 *
 * This function gets in transaction checkpointed FPR registers.
 *
@@ -247,7 +226,7 @@ int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset)
 *};
 */
int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
		struct membuf to)
{
	u64 buf[33];
	int i;
@@ -266,7 +245,7 @@ int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
	for (i = 0; i < 32 ; i++)
		buf[i] = target->thread.TS_CKFPR(i);
	buf[32] = target->thread.ckfp_state.fpscr;
	return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
	return membuf_write(&to, buf, sizeof(buf));
}

/**
@@ -344,10 +323,7 @@ int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset)
 * tm_cvmx_get - get CMVX registers
 * @target:	The target task.
 * @regset:	The user regset structure.
 * @pos:	The buffer position.
 * @count:	Number of bytes to copy.
 * @kbuf:	Kernel buffer to copy from.
 * @ubuf:	User buffer to copy into.
 * @to:		Destination of copy.
 *
 * This function gets in transaction checkpointed VMX registers.
 *
@@ -363,10 +339,12 @@ int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset)
 *};
 */
int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
		struct membuf to)
{
	int ret;

	union {
		elf_vrreg_t reg;
		u32 word;
	} vrsave;
	BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));

	if (!cpu_has_feature(CPU_FTR_TM))
@@ -380,23 +358,13 @@ int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
	flush_fp_to_thread(target);
	flush_altivec_to_thread(target);

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state,
				  0, 33 * sizeof(vector128));
	if (!ret) {
	membuf_write(&to, &target->thread.ckvr_state, 33 * sizeof(vector128));
	/*
	 * Copy out only the low-order word of vrsave.
	 */
		union {
			elf_vrreg_t reg;
			u32 word;
		} vrsave;
	memset(&vrsave, 0, sizeof(vrsave));
	vrsave.word = target->thread.ckvrsave;
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
					  33 * sizeof(vector128), -1);
	}

	return ret;
	return membuf_write(&to, &vrsave, sizeof(vrsave));
}

/**
@@ -484,10 +452,7 @@ int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset)
 * tm_cvsx_get - get CVSX registers
 * @target:	The target task.
 * @regset:	The user regset structure.
 * @pos:	The buffer position.
 * @count:	Number of bytes to copy.
 * @kbuf:	Kernel buffer to copy from.
 * @ubuf:	User buffer to copy into.
 * @to:		Destination of copy.
 *
 * This function gets in transaction checkpointed VSX registers.
 *
@@ -501,10 +466,10 @@ int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset)
 *};
 */
int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
		struct membuf to)
{
	u64 buf[32];
	int ret, i;
	int i;

	if (!cpu_has_feature(CPU_FTR_TM))
		return -ENODEV;
@@ -520,10 +485,7 @@ int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset,

	for (i = 0; i < 32 ; i++)
		buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  buf, 0, 32 * sizeof(double));

	return ret;
	return membuf_write(&to, buf, 32 * sizeof(double));
}

/**
@@ -597,10 +559,7 @@ int tm_spr_active(struct task_struct *target, const struct user_regset *regset)
 * tm_spr_get - get the TM related SPR registers
 * @target:	The target task.
 * @regset:	The user regset structure.
 * @pos:	The buffer position.
 * @count:	Number of bytes to copy.
 * @kbuf:	Kernel buffer to copy from.
 * @ubuf:	User buffer to copy into.
 * @to:		Destination of copy.
 *
 * This function gets transactional memory related SPR registers.
 * The userspace interface buffer layout is as follows.
@@ -612,10 +571,8 @@ int tm_spr_active(struct task_struct *target, const struct user_regset *regset)
 * };
 */
int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
	       unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
	       struct membuf to)
{
	int ret;

	/* Build tests */
	BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
	BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
@@ -630,21 +587,11 @@ int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
	flush_altivec_to_thread(target);

	/* TFHAR register */
	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  &target->thread.tm_tfhar, 0, sizeof(u64));

	membuf_write(&to, &target->thread.tm_tfhar, sizeof(u64));
	/* TEXASR register */
	if (!ret)
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  &target->thread.tm_texasr, sizeof(u64),
					  2 * sizeof(u64));

	membuf_write(&to, &target->thread.tm_texasr, sizeof(u64));
	/* TFIAR register */
	if (!ret)
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  &target->thread.tm_tfiar,
					  2 * sizeof(u64), 3 * sizeof(u64));
	return ret;
	return membuf_write(&to, &target->thread.tm_tfiar, sizeof(u64));
}

/**
@@ -714,19 +661,15 @@ int tm_tar_active(struct task_struct *target, const struct user_regset *regset)
}

int tm_tar_get(struct task_struct *target, const struct user_regset *regset,
	       unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
	       struct membuf to)
{
	int ret;

	if (!cpu_has_feature(CPU_FTR_TM))
		return -ENODEV;

	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
		return -ENODATA;

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  &target->thread.tm_tar, 0, sizeof(u64));
	return ret;
	return membuf_write(&to, &target->thread.tm_tar, sizeof(u64));
}

int tm_tar_set(struct task_struct *target, const struct user_regset *regset,
@@ -759,19 +702,15 @@ int tm_ppr_active(struct task_struct *target, const struct user_regset *regset)


int tm_ppr_get(struct task_struct *target, const struct user_regset *regset,
	       unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
	       struct membuf to)
{
	int ret;

	if (!cpu_has_feature(CPU_FTR_TM))
		return -ENODEV;

	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
		return -ENODATA;

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  &target->thread.tm_ppr, 0, sizeof(u64));
	return ret;
	return membuf_write(&to, &target->thread.tm_ppr, sizeof(u64));
}

int tm_ppr_set(struct task_struct *target, const struct user_regset *regset,
@@ -803,19 +742,15 @@ int tm_dscr_active(struct task_struct *target, const struct user_regset *regset)
}

int tm_dscr_get(struct task_struct *target, const struct user_regset *regset,
		unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
		struct membuf to)
{
	int ret;

	if (!cpu_has_feature(CPU_FTR_TM))
		return -ENODEV;

	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
		return -ENODATA;

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  &target->thread.tm_dscr, 0, sizeof(u64));
	return ret;
	return membuf_write(&to, &target->thread.tm_dscr, sizeof(u64));
}

int tm_dscr_set(struct task_struct *target, const struct user_regset *regset,
@@ -836,10 +771,11 @@ int tm_dscr_set(struct task_struct *target, const struct user_regset *regset,
}

int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset,
		  unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
		  struct membuf to)
{
	return gpr32_get_common(target, regset, pos, count, kbuf, ubuf,
	gpr32_get_common(target, regset, to,
				&target->thread.ckpt_regs.gpr[0]);
	return membuf_zero(&to, ELF_NGREG * sizeof(u32));
}

int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset,
Loading