162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * System call callback functions for SPUs 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#undef DEBUG 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/kallsyms.h> 962306a36Sopenharmony_ci#include <linux/export.h> 1062306a36Sopenharmony_ci#include <linux/syscalls.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <asm/spu.h> 1362306a36Sopenharmony_ci#include <asm/syscalls.h> 1462306a36Sopenharmony_ci#include <asm/unistd.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * This table defines the system calls that an SPU can call. 1862306a36Sopenharmony_ci * It is currently a subset of the 64 bit powerpc system calls, 1962306a36Sopenharmony_ci * with the exact semantics. 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * The reasons for disabling some of the system calls are: 2262306a36Sopenharmony_ci * 1. They interact with the way SPU syscalls are handled 2362306a36Sopenharmony_ci * and we can't let them execute ever: 2462306a36Sopenharmony_ci * restart_syscall, exit, for, execve, ptrace, ... 2562306a36Sopenharmony_ci * 2. They are deprecated and replaced by other means: 2662306a36Sopenharmony_ci * uselib, pciconfig_*, sysfs, ... 2762306a36Sopenharmony_ci * 3. They are somewhat interacting with the system in a way 2862306a36Sopenharmony_ci * we don't want an SPU to: 2962306a36Sopenharmony_ci * reboot, init_module, mount, kexec_load 3062306a36Sopenharmony_ci * 4. They are optional and we can't rely on them being 3162306a36Sopenharmony_ci * linked into the kernel. Unfortunately, the cond_syscall 3262306a36Sopenharmony_ci * helper does not work here as it does not add the necessary 3362306a36Sopenharmony_ci * opd symbols: 3462306a36Sopenharmony_ci * mbind, mq_open, ipc, ... 3562306a36Sopenharmony_ci */ 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic const syscall_fn spu_syscall_table[] = { 3862306a36Sopenharmony_ci#define __SYSCALL_WITH_COMPAT(nr, entry, compat) __SYSCALL(nr, entry) 3962306a36Sopenharmony_ci#define __SYSCALL(nr, entry) [nr] = (void *) entry, 4062306a36Sopenharmony_ci#include <asm/syscall_table_spu.h> 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cilong spu_sys_callback(struct spu_syscall_block *s) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci syscall_fn syscall; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) { 4862306a36Sopenharmony_ci pr_debug("%s: invalid syscall #%lld", __func__, s->nr_ret); 4962306a36Sopenharmony_ci return -ENOSYS; 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci syscall = spu_syscall_table[s->nr_ret]; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci pr_debug("SPU-syscall " 5562306a36Sopenharmony_ci "%pSR:syscall%lld(%llx, %llx, %llx, %llx, %llx, %llx)\n", 5662306a36Sopenharmony_ci syscall, 5762306a36Sopenharmony_ci s->nr_ret, 5862306a36Sopenharmony_ci s->parm[0], s->parm[1], s->parm[2], 5962306a36Sopenharmony_ci s->parm[3], s->parm[4], s->parm[5]); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return syscall(s->parm[0], s->parm[1], s->parm[2], 6262306a36Sopenharmony_ci s->parm[3], s->parm[4], s->parm[5]); 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(spu_sys_callback); 65