cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

regset.c (1898B)


      1// 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->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->regset_get(target, regset,
     24			   (struct membuf){.p = p, .left = size});
     25	if (res < 0) {
     26		kfree(to_free);
     27		return res;
     28	}
     29	*data = p;
     30	return size - res;
     31}
     32
     33int regset_get(struct task_struct *target,
     34	       const struct user_regset *regset,
     35	       unsigned int size,
     36	       void *data)
     37{
     38	return __regset_get(target, regset, size, &data);
     39}
     40EXPORT_SYMBOL(regset_get);
     41
     42int regset_get_alloc(struct task_struct *target,
     43		     const struct user_regset *regset,
     44		     unsigned int size,
     45		     void **data)
     46{
     47	*data = NULL;
     48	return __regset_get(target, regset, size, data);
     49}
     50EXPORT_SYMBOL(regset_get_alloc);
     51
     52/**
     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
     60 */
     61int copy_regset_to_user(struct task_struct *target,
     62			const struct user_regset_view *view,
     63			unsigned int setno,
     64			unsigned int offset, unsigned int size,
     65			void __user *data)
     66{
     67	const struct user_regset *regset = &view->regsets[setno];
     68	void *buf;
     69	int ret;
     70
     71	ret = regset_get_alloc(target, regset, size, &buf);
     72	if (ret > 0)
     73		ret = copy_to_user(data, buf, ret) ? -EFAULT : 0;
     74	kfree(buf);
     75	return ret;
     76}