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

i915_user_extensions.c (1119B)


      1/*
      2 * SPDX-License-Identifier: MIT
      3 *
      4 * Copyright © 2018 Intel Corporation
      5 */
      6
      7#include <linux/nospec.h>
      8#include <linux/sched/signal.h>
      9#include <linux/uaccess.h>
     10
     11#include <uapi/drm/i915_drm.h>
     12
     13#include "i915_user_extensions.h"
     14#include "i915_utils.h"
     15
     16int i915_user_extensions(struct i915_user_extension __user *ext,
     17			 const i915_user_extension_fn *tbl,
     18			 unsigned int count,
     19			 void *data)
     20{
     21	unsigned int stackdepth = 512;
     22
     23	while (ext) {
     24		int i, err;
     25		u32 name;
     26		u64 next;
     27
     28		if (!stackdepth--) /* recursion vs useful flexibility */
     29			return -E2BIG;
     30
     31		err = check_user_mbz(&ext->flags);
     32		if (err)
     33			return err;
     34
     35		for (i = 0; i < ARRAY_SIZE(ext->rsvd); i++) {
     36			err = check_user_mbz(&ext->rsvd[i]);
     37			if (err)
     38				return err;
     39		}
     40
     41		if (get_user(name, &ext->name))
     42			return -EFAULT;
     43
     44		err = -EINVAL;
     45		if (name < count) {
     46			name = array_index_nospec(name, count);
     47			if (tbl[name])
     48				err = tbl[name](ext, data);
     49		}
     50		if (err)
     51			return err;
     52
     53		if (get_user(next, &ext->next_extension) ||
     54		    overflows_type(next, ext))
     55			return -EFAULT;
     56
     57		ext = u64_to_user_ptr(next);
     58	}
     59
     60	return 0;
     61}