Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * System call callback functions for SPUs
0004  */
0005 
0006 #undef DEBUG
0007 
0008 #include <linux/kallsyms.h>
0009 #include <linux/export.h>
0010 #include <linux/syscalls.h>
0011 
0012 #include <asm/spu.h>
0013 #include <asm/syscalls.h>
0014 #include <asm/unistd.h>
0015 
0016 /*
0017  * This table defines the system calls that an SPU can call.
0018  * It is currently a subset of the 64 bit powerpc system calls,
0019  * with the exact semantics.
0020  *
0021  * The reasons for disabling some of the system calls are:
0022  * 1. They interact with the way SPU syscalls are handled
0023  *    and we can't let them execute ever:
0024  *  restart_syscall, exit, for, execve, ptrace, ...
0025  * 2. They are deprecated and replaced by other means:
0026  *  uselib, pciconfig_*, sysfs, ...
0027  * 3. They are somewhat interacting with the system in a way
0028  *    we don't want an SPU to:
0029  *  reboot, init_module, mount, kexec_load
0030  * 4. They are optional and we can't rely on them being
0031  *    linked into the kernel. Unfortunately, the cond_syscall
0032  *    helper does not work here as it does not add the necessary
0033  *    opd symbols:
0034  *  mbind, mq_open, ipc, ...
0035  */
0036 
0037 static void *spu_syscall_table[] = {
0038 #define __SYSCALL_WITH_COMPAT(nr, entry, compat) __SYSCALL(nr, entry)
0039 #define __SYSCALL(nr, entry) [nr] = entry,
0040 #include <asm/syscall_table_spu.h>
0041 };
0042 
0043 long spu_sys_callback(struct spu_syscall_block *s)
0044 {
0045     long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
0046 
0047     if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) {
0048         pr_debug("%s: invalid syscall #%lld", __func__, s->nr_ret);
0049         return -ENOSYS;
0050     }
0051 
0052     syscall = spu_syscall_table[s->nr_ret];
0053 
0054     pr_debug("SPU-syscall "
0055          "%pSR:syscall%lld(%llx, %llx, %llx, %llx, %llx, %llx)\n",
0056          syscall,
0057          s->nr_ret,
0058          s->parm[0], s->parm[1], s->parm[2],
0059          s->parm[3], s->parm[4], s->parm[5]);
0060 
0061     return syscall(s->parm[0], s->parm[1], s->parm[2],
0062                s->parm[3], s->parm[4], s->parm[5]);
0063 }
0064 EXPORT_SYMBOL_GPL(spu_sys_callback);