From dc12d7968f9c9540494deb1285854b18ca4465ec Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 17 Feb 2020 12:25:14 -0500 Subject: 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: Al Viro --- kernel/regset.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'kernel/regset.c') diff --git a/kernel/regset.c b/kernel/regset.c index 6b39fa0993ec..0a610983ce43 100644 --- a/kernel/regset.c +++ b/kernel/regset.c @@ -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; +} -- cgit v1.2.3