Commit dc12d796 authored by Al Viro's avatar Al Viro
Browse files

copy_regset_to_user(): do all copyout at once.



Turn copy_regset_to_user() into regset_get_alloc() + copy_to_user().
Now all ->get() calls have a kernel buffer as destination.

Note that we'd already eliminated the callers of copy_regset_to_user()
with non-zero offset; now that argument is simply unused.

Uninlined, while we are at it.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 1e56f6d2
Loading
Loading
Loading
Loading
+4 −25
Original line number Diff line number Diff line
@@ -362,31 +362,10 @@ extern int regset_get_alloc(struct task_struct *target,
			    unsigned int size,
			    void **data);

/**
 * copy_regset_to_user - fetch a thread's user_regset data into user memory
 * @target:	thread to be examined
 * @view:	&struct user_regset_view describing user thread machine state
 * @setno:	index in @view->regsets
 * @offset:	offset into the regset data, in bytes
 * @size:	amount of data to copy, in bytes
 * @data:	user-mode pointer to copy into
 */
static inline int copy_regset_to_user(struct task_struct *target,
extern int copy_regset_to_user(struct task_struct *target,
			       const struct user_regset_view *view,
				      unsigned int setno,
				      unsigned int offset, unsigned int size,
				      void __user *data)
{
	const struct user_regset *regset = &view->regsets[setno];

	if (!regset->get)
		return -EOPNOTSUPP;

	if (!access_ok(data, size))
		return -EFAULT;

	return regset->get(target, regset, offset, size, NULL, data);
}
			       unsigned int setno, unsigned int offset,
			       unsigned int size, void __user *data);

/**
 * copy_regset_from_user - store into thread's user_regset data from user memory
+26 −0
Original line number Diff line number Diff line
@@ -52,3 +52,29 @@ int regset_get_alloc(struct task_struct *target,
	return __regset_get(target, regset, size, data);
}
EXPORT_SYMBOL(regset_get_alloc);

/**
 * copy_regset_to_user - fetch a thread's user_regset data into user memory
 * @target:	thread to be examined
 * @view:	&struct user_regset_view describing user thread machine state
 * @setno:	index in @view->regsets
 * @offset:	offset into the regset data, in bytes
 * @size:	amount of data to copy, in bytes
 * @data:	user-mode pointer to copy into
 */
int copy_regset_to_user(struct task_struct *target,
			const struct user_regset_view *view,
			unsigned int setno,
			unsigned int offset, unsigned int size,
			void __user *data)
{
	const struct user_regset *regset = &view->regsets[setno];
	void *buf;
	int ret;

	ret = regset_get_alloc(target, regset, size, &buf);
	if (ret > 0)
		ret = copy_to_user(data, buf, ret) ? -EFAULT : 0;
	kfree(buf);
	return ret;
}