18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  S390 version
48c2ecf20Sopenharmony_ci *    Copyright IBM Corp. 1999, 2000
58c2ecf20Sopenharmony_ci *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
68c2ecf20Sopenharmony_ci *               Thomas Spatzier (tspat@de.ibm.com)
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *  Derived from "arch/i386/kernel/sys_i386.c"
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci *  This file contains various random system calls that
118c2ecf20Sopenharmony_ci *  have a non-standard calling sequence on the Linux/s390
128c2ecf20Sopenharmony_ci *  platform.
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/errno.h>
168c2ecf20Sopenharmony_ci#include <linux/sched.h>
178c2ecf20Sopenharmony_ci#include <linux/mm.h>
188c2ecf20Sopenharmony_ci#include <linux/fs.h>
198c2ecf20Sopenharmony_ci#include <linux/smp.h>
208c2ecf20Sopenharmony_ci#include <linux/sem.h>
218c2ecf20Sopenharmony_ci#include <linux/msg.h>
228c2ecf20Sopenharmony_ci#include <linux/shm.h>
238c2ecf20Sopenharmony_ci#include <linux/stat.h>
248c2ecf20Sopenharmony_ci#include <linux/syscalls.h>
258c2ecf20Sopenharmony_ci#include <linux/mman.h>
268c2ecf20Sopenharmony_ci#include <linux/file.h>
278c2ecf20Sopenharmony_ci#include <linux/utsname.h>
288c2ecf20Sopenharmony_ci#include <linux/personality.h>
298c2ecf20Sopenharmony_ci#include <linux/unistd.h>
308c2ecf20Sopenharmony_ci#include <linux/ipc.h>
318c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
328c2ecf20Sopenharmony_ci#include "entry.h"
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/*
358c2ecf20Sopenharmony_ci * Perform the mmap() system call. Linux for S/390 isn't able to handle more
368c2ecf20Sopenharmony_ci * than 5 system call parameters, so this system call uses a memory block
378c2ecf20Sopenharmony_ci * for parameter passing.
388c2ecf20Sopenharmony_ci */
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cistruct s390_mmap_arg_struct {
418c2ecf20Sopenharmony_ci	unsigned long addr;
428c2ecf20Sopenharmony_ci	unsigned long len;
438c2ecf20Sopenharmony_ci	unsigned long prot;
448c2ecf20Sopenharmony_ci	unsigned long flags;
458c2ecf20Sopenharmony_ci	unsigned long fd;
468c2ecf20Sopenharmony_ci	unsigned long offset;
478c2ecf20Sopenharmony_ci};
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ciSYSCALL_DEFINE1(mmap2, struct s390_mmap_arg_struct __user *, arg)
508c2ecf20Sopenharmony_ci{
518c2ecf20Sopenharmony_ci	struct s390_mmap_arg_struct a;
528c2ecf20Sopenharmony_ci	int error = -EFAULT;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	if (copy_from_user(&a, arg, sizeof(a)))
558c2ecf20Sopenharmony_ci		goto out;
568c2ecf20Sopenharmony_ci	error = ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
578c2ecf20Sopenharmony_ciout:
588c2ecf20Sopenharmony_ci	return error;
598c2ecf20Sopenharmony_ci}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci#ifdef CONFIG_SYSVIPC
628c2ecf20Sopenharmony_ci/*
638c2ecf20Sopenharmony_ci * sys_ipc() is the de-multiplexer for the SysV IPC calls.
648c2ecf20Sopenharmony_ci */
658c2ecf20Sopenharmony_ciSYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
668c2ecf20Sopenharmony_ci		unsigned long, third, void __user *, ptr)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci	if (call >> 16)
698c2ecf20Sopenharmony_ci		return -EINVAL;
708c2ecf20Sopenharmony_ci	/* The s390 sys_ipc variant has only five parameters instead of six
718c2ecf20Sopenharmony_ci	 * like the generic variant. The only difference is the handling of
728c2ecf20Sopenharmony_ci	 * the SEMTIMEDOP subcall where on s390 the third parameter is used
738c2ecf20Sopenharmony_ci	 * as a pointer to a struct timespec where the generic variant uses
748c2ecf20Sopenharmony_ci	 * the fifth parameter.
758c2ecf20Sopenharmony_ci	 * Therefore we can call the generic variant by simply passing the
768c2ecf20Sopenharmony_ci	 * third parameter also as fifth parameter.
778c2ecf20Sopenharmony_ci	 */
788c2ecf20Sopenharmony_ci	return ksys_ipc(call, first, second, third, ptr, third);
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci#endif /* CONFIG_SYSVIPC */
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ciSYSCALL_DEFINE1(s390_personality, unsigned int, personality)
838c2ecf20Sopenharmony_ci{
848c2ecf20Sopenharmony_ci	unsigned int ret = current->personality;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	if (personality(current->personality) == PER_LINUX32 &&
878c2ecf20Sopenharmony_ci	    personality(personality) == PER_LINUX)
888c2ecf20Sopenharmony_ci		personality |= PER_LINUX32;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	if (personality != 0xffffffff)
918c2ecf20Sopenharmony_ci		set_personality(personality);
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	if (personality(ret) == PER_LINUX32)
948c2ecf20Sopenharmony_ci		ret &= ~PER_LINUX32;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	return ret;
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ciSYSCALL_DEFINE0(ni_syscall)
1008c2ecf20Sopenharmony_ci{
1018c2ecf20Sopenharmony_ci	return -ENOSYS;
1028c2ecf20Sopenharmony_ci}
103