Skip to content

Commit dc12d79

Browse files
author
Al Viro
committed
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 <[email protected]>
1 parent 1e56f6d commit dc12d79

File tree

2 files changed

+30
-25
lines changed

2 files changed

+30
-25
lines changed

include/linux/regset.h

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -362,31 +362,10 @@ extern int regset_get_alloc(struct task_struct *target,
362362
unsigned int size,
363363
void **data);
364364

365-
/**
366-
* copy_regset_to_user - fetch a thread's user_regset data into user memory
367-
* @target: thread to be examined
368-
* @view: &struct user_regset_view describing user thread machine state
369-
* @setno: index in @view->regsets
370-
* @offset: offset into the regset data, in bytes
371-
* @size: amount of data to copy, in bytes
372-
* @data: user-mode pointer to copy into
373-
*/
374-
static inline int copy_regset_to_user(struct task_struct *target,
375-
const struct user_regset_view *view,
376-
unsigned int setno,
377-
unsigned int offset, unsigned int size,
378-
void __user *data)
379-
{
380-
const struct user_regset *regset = &view->regsets[setno];
381-
382-
if (!regset->get)
383-
return -EOPNOTSUPP;
384-
385-
if (!access_ok(data, size))
386-
return -EFAULT;
387-
388-
return regset->get(target, regset, offset, size, NULL, data);
389-
}
365+
extern int copy_regset_to_user(struct task_struct *target,
366+
const struct user_regset_view *view,
367+
unsigned int setno, unsigned int offset,
368+
unsigned int size, void __user *data);
390369

391370
/**
392371
* copy_regset_from_user - store into thread's user_regset data from user memory

kernel/regset.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,29 @@ int regset_get_alloc(struct task_struct *target,
5252
return __regset_get(target, regset, size, data);
5353
}
5454
EXPORT_SYMBOL(regset_get_alloc);
55+
56+
/**
57+
* copy_regset_to_user - fetch a thread's user_regset data into user memory
58+
* @target: thread to be examined
59+
* @view: &struct user_regset_view describing user thread machine state
60+
* @setno: index in @view->regsets
61+
* @offset: offset into the regset data, in bytes
62+
* @size: amount of data to copy, in bytes
63+
* @data: user-mode pointer to copy into
64+
*/
65+
int copy_regset_to_user(struct task_struct *target,
66+
const struct user_regset_view *view,
67+
unsigned int setno,
68+
unsigned int offset, unsigned int size,
69+
void __user *data)
70+
{
71+
const struct user_regset *regset = &view->regsets[setno];
72+
void *buf;
73+
int ret;
74+
75+
ret = regset_get_alloc(target, regset, size, &buf);
76+
if (ret > 0)
77+
ret = copy_to_user(data, buf, ret) ? -EFAULT : 0;
78+
kfree(buf);
79+
return ret;
80+
}

0 commit comments

Comments
 (0)