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

syscalls.c (2224B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/file.h>
      3#include <linux/fs.h>
      4#include <linux/export.h>
      5#include <linux/mount.h>
      6#include <linux/namei.h>
      7#include <linux/slab.h>
      8
      9#include <linux/uaccess.h>
     10
     11#include "spufs.h"
     12
     13/**
     14 * sys_spu_run - run code loaded into an SPU
     15 *
     16 * @unpc:    next program counter for the SPU
     17 * @ustatus: status of the SPU
     18 *
     19 * This system call transfers the control of execution of a
     20 * user space thread to an SPU. It will return when the
     21 * SPU has finished executing or when it hits an error
     22 * condition and it will be interrupted if a signal needs
     23 * to be delivered to a handler in user space.
     24 *
     25 * The next program counter is set to the passed value
     26 * before the SPU starts fetching code and the user space
     27 * pointer gets updated with the new value when returning
     28 * from kernel space.
     29 *
     30 * The status value returned from spu_run reflects the
     31 * value of the spu_status register after the SPU has stopped.
     32 *
     33 */
     34static long do_spu_run(struct file *filp,
     35			__u32 __user *unpc,
     36			__u32 __user *ustatus)
     37{
     38	long ret;
     39	struct spufs_inode_info *i;
     40	u32 npc, status;
     41
     42	ret = -EFAULT;
     43	if (get_user(npc, unpc))
     44		goto out;
     45
     46	/* check if this file was created by spu_create */
     47	ret = -EINVAL;
     48	if (filp->f_op != &spufs_context_fops)
     49		goto out;
     50
     51	i = SPUFS_I(file_inode(filp));
     52	ret = spufs_run_spu(i->i_ctx, &npc, &status);
     53
     54	if (put_user(npc, unpc))
     55		ret = -EFAULT;
     56
     57	if (ustatus && put_user(status, ustatus))
     58		ret = -EFAULT;
     59out:
     60	return ret;
     61}
     62
     63static long do_spu_create(const char __user *pathname, unsigned int flags,
     64		umode_t mode, struct file *neighbor)
     65{
     66	struct path path;
     67	struct dentry *dentry;
     68	int ret;
     69
     70	dentry = user_path_create(AT_FDCWD, pathname, &path, LOOKUP_DIRECTORY);
     71	ret = PTR_ERR(dentry);
     72	if (!IS_ERR(dentry)) {
     73		ret = spufs_create(&path, dentry, flags, mode, neighbor);
     74		done_path_create(&path, dentry);
     75	}
     76
     77	return ret;
     78}
     79
     80struct spufs_calls spufs_calls = {
     81	.create_thread = do_spu_create,
     82	.spu_run = do_spu_run,
     83	.notify_spus_active = do_notify_spus_active,
     84	.owner = THIS_MODULE,
     85#ifdef CONFIG_COREDUMP
     86	.coredump_extra_notes_size = spufs_coredump_extra_notes_size,
     87	.coredump_extra_notes_write = spufs_coredump_extra_notes_write,
     88#endif
     89};