Commit 8f032921 authored by Al Viro's avatar Al Viro
Browse files

sparc64: get rid of odd callers of copy_regset_to_user()



same as for sparc32, and that's it - no more caller of ->get() with
non-zero pos.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 87d80533
Loading
Loading
Loading
Loading
+136 −39
Original line number Diff line number Diff line
@@ -258,7 +258,7 @@ static int genregs64_get(struct task_struct *target,
	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  regs->u_regs,
				  0, 16 * sizeof(u64));
	if (!ret && count && pos < (32 * sizeof(u64))) {
	if (!ret && count) {
		struct reg_window window;

		if (regwindow64_get(target, regs, &window))
@@ -506,6 +506,57 @@ static const struct user_regset sparc64_regsets[] = {
	},
};

static int getregs64_get(struct task_struct *target,
			 const struct user_regset *regset,
			 unsigned int pos, unsigned int count,
			 void *kbuf, void __user *ubuf)
{
	const struct pt_regs *regs = task_pt_regs(target);
	int ret;

	if (target == current)
		flushw_user();

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  regs->u_regs + 1,
				  0, 15 * sizeof(u64));
	if (!ret)
		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
				  15 * sizeof(u64), 16 * sizeof(u64));
	if (!ret) {
		/* TSTATE, TPC, TNPC */
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  &regs->tstate,
					  16 * sizeof(u64),
					  19 * sizeof(u64));
	}
	if (!ret) {
		unsigned long y = regs->y;

		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  &y,
					  19 * sizeof(u64),
					  20 * sizeof(u64));
	}
	return ret;
}

static const struct user_regset ptrace64_regsets[] = {
	/* Format is:
	 *      G1 --> G7
	 *      O0 --> O7
	 *	0
	 *      TSTATE, TPC, TNPC, Y
	 */
	[REGSET_GENERAL] = {
		.n = 20, .size = sizeof(u64), .get = getregs64_get,
	},
};

static const struct user_regset_view ptrace64_view = {
	.regsets = ptrace64_regsets, .n = ARRAY_SIZE(ptrace64_regsets)
};

static const struct user_regset_view user_sparc64_view = {
	.name = "sparc64", .e_machine = EM_SPARCV9,
	.regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets)
@@ -533,7 +584,7 @@ static int genregs32_get(struct task_struct *target,
		for (; count > 0 && pos < 16; count--)
			*k++ = regs->u_regs[pos++];

		if (count && pos < 32) {
		if (count) {
			if (get_from_target(target, regs->u_regs[UREG_I6],
					uregs, sizeof(uregs)))
				return -EFAULT;
@@ -545,7 +596,7 @@ static int genregs32_get(struct task_struct *target,
		for (; count > 0 && pos < 16; count--)
			if (put_user((compat_ulong_t) regs->u_regs[pos++], u++))
				return -EFAULT;
		if (count && pos < 32) {
		if (count) {
			if (get_from_target(target, regs->u_regs[UREG_I6],
					uregs, sizeof(uregs)))
				return -EFAULT;
@@ -840,6 +891,76 @@ static const struct user_regset sparc32_regsets[] = {
	},
};

static int getregs_get(struct task_struct *target,
		       const struct user_regset *regset,
		       unsigned int pos, unsigned int count,
		       void *kbuf, void __user *ubuf)
{
	const struct pt_regs *regs = task_pt_regs(target);
	u32 uregs[19];
	int i;

	if (target == current)
		flushw_user();

	uregs[0] = tstate_to_psr(regs->tstate);
	uregs[1] = regs->tpc;
	uregs[2] = regs->tnpc;
	uregs[3] = regs->y;
	for (i = 1; i < 16; i++)
		uregs[3 + i] = regs->u_regs[i];
	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				   uregs,
				   0, 19 * sizeof(u32));
}

static int getfpregs_get(struct task_struct *target,
			const struct user_regset *regset,
			unsigned int pos, unsigned int count,
			void *kbuf, void __user *ubuf)
{
	const unsigned long *fpregs = task_thread_info(target)->fpregs;
	unsigned long fprs;
	compat_ulong_t fsr;
	int ret = 0;

	if (target == current)
		save_and_clear_fpu();

	fprs = task_thread_info(target)->fpsaved[0];
	if (fprs & FPRS_FEF) {
		fsr = task_thread_info(target)->xfsr[0];
	} else {
		fsr = 0;
	}

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  fpregs,
				  0, 32 * sizeof(u32));
	if (!ret)
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  &fsr,
					  32 * sizeof(u32),
					  33 * sizeof(u32));
	if (!ret)
		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
					  33 * sizeof(u32), 68 * sizeof(u32));
	return ret;
}

static const struct user_regset ptrace32_regsets[] = {
	[REGSET_GENERAL] = {
		.n = 19, .size = sizeof(u32), .get = getregs_get,
	},
	[REGSET_FP] = {
		.n = 68, .size = sizeof(u32), .get = getfpregs_get,
	},
};

static const struct user_regset_view ptrace32_view = {
	.regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets)
};

static const struct user_regset_view user_sparc32_view = {
	.name = "sparc", .e_machine = EM_SPARC,
	.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
@@ -889,15 +1010,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
		break;

	case PTRACE_GETREGS:
		ret = copy_regset_to_user(child, view, REGSET_GENERAL,
					  32 * sizeof(u32),
					  4 * sizeof(u32),
					  &pregs->psr);
		if (!ret)
			ret = copy_regset_to_user(child, view, REGSET_GENERAL,
						  1 * sizeof(u32),
						  15 * sizeof(u32),
						  &pregs->u_regs[0]);
		ret = copy_regset_to_user(child, &ptrace32_view,
					  REGSET_GENERAL, 0,
					  19 * sizeof(u32),
					  pregs);
		break;

	case PTRACE_SETREGS:
@@ -913,22 +1029,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
		break;

	case PTRACE_GETFPREGS:
		ret = copy_regset_to_user(child, view, REGSET_FP,
					  0 * sizeof(u32),
					  32 * sizeof(u32),
					  &fps->regs[0]);
		if (!ret)
			ret = copy_regset_to_user(child, view, REGSET_FP,
						  33 * sizeof(u32),
						  1 * sizeof(u32),
						  &fps->fsr);
		if (!ret) {
			if (__put_user(0, &fps->flags) ||
			    __put_user(0, &fps->extra) ||
			    __put_user(0, &fps->fpqd) ||
			    clear_user(&fps->fpq[0], 32 * sizeof(unsigned int)))
				ret = -EFAULT;
		}
		ret = copy_regset_to_user(child, &ptrace32_view,
					  REGSET_FP, 0,
					  68 * sizeof(u32),
					  fps);
		break;

	case PTRACE_SETFPREGS:
@@ -999,17 +1103,10 @@ long arch_ptrace(struct task_struct *child, long request,
		break;

	case PTRACE_GETREGS64:
		ret = copy_regset_to_user(child, view, REGSET_GENERAL,
					  1 * sizeof(u64),
					  15 * sizeof(u64),
					  &pregs->u_regs[0]);
		if (!ret) {
			/* XXX doesn't handle 'y' register correctly XXX */
			ret = copy_regset_to_user(child, view, REGSET_GENERAL,
						  32 * sizeof(u64),
						  4 * sizeof(u64),
						  &pregs->tstate);
		}
		ret = copy_regset_to_user(child, &ptrace64_view,
					  REGSET_GENERAL, 0,
					  19 * sizeof(u64),
					  pregs);
		break;

	case PTRACE_SETREGS64: