1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/export.h>
3 #include <linux/slab.h>
4 #include <linux/regset.h>
6 static int __regset_get(struct task_struct
*target
,
7 const struct user_regset
*regset
,
11 void *p
= *data
, *to_free
= NULL
;
14 if (!regset
->regset_get
)
16 if (size
> regset
->n
* regset
->size
)
17 size
= regset
->n
* regset
->size
;
19 to_free
= p
= kzalloc(size
, GFP_KERNEL
);
23 res
= regset
->regset_get(target
, regset
,
24 (struct membuf
){.p
= p
, .left
= size
});
33 int regset_get(struct task_struct
*target
,
34 const struct user_regset
*regset
,
38 return __regset_get(target
, regset
, size
, &data
);
40 EXPORT_SYMBOL(regset_get
);
42 int regset_get_alloc(struct task_struct
*target
,
43 const struct user_regset
*regset
,
48 return __regset_get(target
, regset
, size
, data
);
50 EXPORT_SYMBOL(regset_get_alloc
);
53 * copy_regset_to_user - fetch a thread's user_regset data into user memory
54 * @target: thread to be examined
55 * @view: &struct user_regset_view describing user thread machine state
56 * @setno: index in @view->regsets
57 * @offset: offset into the regset data, in bytes
58 * @size: amount of data to copy, in bytes
59 * @data: user-mode pointer to copy into
61 int copy_regset_to_user(struct task_struct
*target
,
62 const struct user_regset_view
*view
,
64 unsigned int offset
, unsigned int size
,
67 const struct user_regset
*regset
= &view
->regsets
[setno
];
71 ret
= regset_get_alloc(target
, regset
, size
, &buf
);
73 ret
= copy_to_user(data
, buf
, ret
) ? -EFAULT
: 0;