blob: 6b39fa0993ecab4bbdf4df2652af17218f4df871 [file] [log] [blame]
Al Virob4e9c952020-06-01 19:42:40 -04001// SPDX-License-Identifier: GPL-2.0-only
2#include <linux/export.h>
3#include <linux/slab.h>
4#include <linux/regset.h>
5
6static int __regset_get(struct task_struct *target,
7 const struct user_regset *regset,
8 unsigned int size,
9 void **data)
10{
11 void *p = *data, *to_free = NULL;
12 int res;
13
14 if (!regset->get)
15 return -EOPNOTSUPP;
16 if (size > regset->n * regset->size)
17 size = regset->n * regset->size;
18 if (!p) {
19 to_free = p = kzalloc(size, GFP_KERNEL);
20 if (!p)
21 return -ENOMEM;
22 }
23 res = regset->get(target, regset, 0, size, p, NULL);
24 if (unlikely(res < 0)) {
25 kfree(to_free);
26 return res;
27 }
28 *data = p;
29 if (regset->get_size) { // arm64-only kludge, will go away
30 unsigned max_size = regset->get_size(target, regset);
31 if (size > max_size)
32 size = max_size;
33 }
34 return size;
35}
36
37int regset_get(struct task_struct *target,
38 const struct user_regset *regset,
39 unsigned int size,
40 void *data)
41{
42 return __regset_get(target, regset, size, &data);
43}
44EXPORT_SYMBOL(regset_get);
45
46int regset_get_alloc(struct task_struct *target,
47 const struct user_regset *regset,
48 unsigned int size,
49 void **data)
50{
51 *data = NULL;
52 return __regset_get(target, regset, size, data);
53}
54EXPORT_SYMBOL(regset_get_alloc);