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