12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
230286ef6SPaul Mackerras /*
3e2375062SNicholas Piggin * sys_ppc32.c: 32-bit system calls with complex calling conventions.
430286ef6SPaul Mackerras *
530286ef6SPaul Mackerras * Copyright (C) 2001 IBM
630286ef6SPaul Mackerras * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
730286ef6SPaul Mackerras * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
830286ef6SPaul Mackerras *
9e2375062SNicholas Piggin * 32-bit system calls with 64-bit arguments pass those in register pairs.
10e2375062SNicholas Piggin * This must be specially dealt with on 64-bit kernels. The compat_arg_u64_dual
11e2375062SNicholas Piggin * in generic compat syscalls is not always usable because the register
12e2375062SNicholas Piggin * pairing is constrained depending on preceding arguments.
13e2375062SNicholas Piggin *
14e2375062SNicholas Piggin * An analogous problem exists on 32-bit kernels with ARCH_HAS_SYSCALL_WRAPPER,
15e2375062SNicholas Piggin * the defined system call functions take the pt_regs as an argument, and there
16e2375062SNicholas Piggin * is a mapping macro which maps registers to arguments
17e2375062SNicholas Piggin * (SC_POWERPC_REGS_TO_ARGS) which also does not deal with these 64-bit
18e2375062SNicholas Piggin * arguments.
19e2375062SNicholas Piggin *
20e2375062SNicholas Piggin * This file contains these system calls.
2130286ef6SPaul Mackerras */
2230286ef6SPaul Mackerras
2330286ef6SPaul Mackerras #include <linux/kernel.h>
2430286ef6SPaul Mackerras #include <linux/sched.h>
2530286ef6SPaul Mackerras #include <linux/fs.h>
2630286ef6SPaul Mackerras #include <linux/mm.h>
2730286ef6SPaul Mackerras #include <linux/file.h>
2830286ef6SPaul Mackerras #include <linux/signal.h>
2930286ef6SPaul Mackerras #include <linux/resource.h>
3030286ef6SPaul Mackerras #include <linux/times.h>
3130286ef6SPaul Mackerras #include <linux/smp.h>
3230286ef6SPaul Mackerras #include <linux/sem.h>
3330286ef6SPaul Mackerras #include <linux/msg.h>
3430286ef6SPaul Mackerras #include <linux/shm.h>
3530286ef6SPaul Mackerras #include <linux/poll.h>
3630286ef6SPaul Mackerras #include <linux/personality.h>
3730286ef6SPaul Mackerras #include <linux/stat.h>
3830286ef6SPaul Mackerras #include <linux/in.h>
3930286ef6SPaul Mackerras #include <linux/syscalls.h>
4030286ef6SPaul Mackerras #include <linux/unistd.h>
4130286ef6SPaul Mackerras #include <linux/sysctl.h>
4230286ef6SPaul Mackerras #include <linux/binfmts.h>
4330286ef6SPaul Mackerras #include <linux/security.h>
4430286ef6SPaul Mackerras #include <linux/compat.h>
4530286ef6SPaul Mackerras #include <linux/ptrace.h>
4630286ef6SPaul Mackerras #include <linux/elf.h>
47cba4fbbfSAdrian Bunk #include <linux/ipc.h>
485a0e3ad6STejun Heo #include <linux/slab.h>
4930286ef6SPaul Mackerras
5030286ef6SPaul Mackerras #include <asm/ptrace.h>
5130286ef6SPaul Mackerras #include <asm/types.h>
527c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
5330286ef6SPaul Mackerras #include <asm/unistd.h>
5430286ef6SPaul Mackerras #include <asm/time.h>
5530286ef6SPaul Mackerras #include <asm/mmu_context.h>
5630286ef6SPaul Mackerras #include <asm/ppc-pci.h>
57369cf4b9SArnd Bergmann #include <asm/syscalls.h>
58ae3a197eSDavid Howells #include <asm/switch_to.h>
5930286ef6SPaul Mackerras
60e2375062SNicholas Piggin #ifdef CONFIG_PPC32
61e2375062SNicholas Piggin #define PPC32_SYSCALL_DEFINE4 SYSCALL_DEFINE4
62e2375062SNicholas Piggin #define PPC32_SYSCALL_DEFINE5 SYSCALL_DEFINE5
63e2375062SNicholas Piggin #define PPC32_SYSCALL_DEFINE6 SYSCALL_DEFINE6
64e2375062SNicholas Piggin #else
65e2375062SNicholas Piggin #define PPC32_SYSCALL_DEFINE4 COMPAT_SYSCALL_DEFINE4
66e2375062SNicholas Piggin #define PPC32_SYSCALL_DEFINE5 COMPAT_SYSCALL_DEFINE5
67e2375062SNicholas Piggin #define PPC32_SYSCALL_DEFINE6 COMPAT_SYSCALL_DEFINE6
68e2375062SNicholas Piggin #endif
69e2375062SNicholas Piggin
PPC32_SYSCALL_DEFINE6(ppc_pread64,unsigned int,fd,char __user *,ubuf,compat_size_t,count,u32,reg6,u32,pos1,u32,pos2)70e2375062SNicholas Piggin PPC32_SYSCALL_DEFINE6(ppc_pread64,
71dec20c50SRohan McLure unsigned int, fd,
72dec20c50SRohan McLure char __user *, ubuf, compat_size_t, count,
73dec20c50SRohan McLure u32, reg6, u32, pos1, u32, pos2)
7430286ef6SPaul Mackerras {
7557f48b4bSWill Springer return ksys_pread64(fd, ubuf, count, merge_64(pos1, pos2));
7630286ef6SPaul Mackerras }
7730286ef6SPaul Mackerras
PPC32_SYSCALL_DEFINE6(ppc_pwrite64,unsigned int,fd,const char __user *,ubuf,compat_size_t,count,u32,reg6,u32,pos1,u32,pos2)78e2375062SNicholas Piggin PPC32_SYSCALL_DEFINE6(ppc_pwrite64,
79dec20c50SRohan McLure unsigned int, fd,
80dec20c50SRohan McLure const char __user *, ubuf, compat_size_t, count,
81dec20c50SRohan McLure u32, reg6, u32, pos1, u32, pos2)
8230286ef6SPaul Mackerras {
8357f48b4bSWill Springer return ksys_pwrite64(fd, ubuf, count, merge_64(pos1, pos2));
8430286ef6SPaul Mackerras }
8530286ef6SPaul Mackerras
PPC32_SYSCALL_DEFINE5(ppc_readahead,int,fd,u32,r4,u32,offset1,u32,offset2,u32,count)86e2375062SNicholas Piggin PPC32_SYSCALL_DEFINE5(ppc_readahead,
87dec20c50SRohan McLure int, fd, u32, r4,
88dec20c50SRohan McLure u32, offset1, u32, offset2, u32, count)
8930286ef6SPaul Mackerras {
9057f48b4bSWill Springer return ksys_readahead(fd, merge_64(offset1, offset2), count);
9130286ef6SPaul Mackerras }
9230286ef6SPaul Mackerras
PPC32_SYSCALL_DEFINE4(ppc_truncate64,const char __user *,path,u32,reg4,unsigned long,len1,unsigned long,len2)93e2375062SNicholas Piggin PPC32_SYSCALL_DEFINE4(ppc_truncate64,
94dec20c50SRohan McLure const char __user *, path, u32, reg4,
95dec20c50SRohan McLure unsigned long, len1, unsigned long, len2)
9630286ef6SPaul Mackerras {
9757f48b4bSWill Springer return ksys_truncate(path, merge_64(len1, len2));
9830286ef6SPaul Mackerras }
9930286ef6SPaul Mackerras
PPC32_SYSCALL_DEFINE4(ppc_ftruncate64,unsigned int,fd,u32,reg4,unsigned long,len1,unsigned long,len2)100e2375062SNicholas Piggin PPC32_SYSCALL_DEFINE4(ppc_ftruncate64,
101dec20c50SRohan McLure unsigned int, fd, u32, reg4,
102dec20c50SRohan McLure unsigned long, len1, unsigned long, len2)
10330286ef6SPaul Mackerras {
10457f48b4bSWill Springer return ksys_ftruncate(fd, merge_64(len1, len2));
10530286ef6SPaul Mackerras }
10630286ef6SPaul Mackerras
PPC32_SYSCALL_DEFINE6(ppc32_fadvise64,int,fd,u32,unused,u32,offset1,u32,offset2,size_t,len,int,advice)107e2375062SNicholas Piggin PPC32_SYSCALL_DEFINE6(ppc32_fadvise64,
108dec20c50SRohan McLure int, fd, u32, unused, u32, offset1, u32, offset2,
109dec20c50SRohan McLure size_t, len, int, advice)
11030286ef6SPaul Mackerras {
11157f48b4bSWill Springer return ksys_fadvise64_64(fd, merge_64(offset1, offset2), len,
11230286ef6SPaul Mackerras advice);
11330286ef6SPaul Mackerras }
11430286ef6SPaul Mackerras
PPC32_SYSCALL_DEFINE6(ppc_sync_file_range2,int,fd,unsigned int,flags,unsigned int,offset1,unsigned int,offset2,unsigned int,nbytes1,unsigned int,nbytes2)115*ce883a2bSAndreas Schwab PPC32_SYSCALL_DEFINE6(ppc_sync_file_range2,
116dec20c50SRohan McLure int, fd, unsigned int, flags,
117dec20c50SRohan McLure unsigned int, offset1, unsigned int, offset2,
118dec20c50SRohan McLure unsigned int, nbytes1, unsigned int, nbytes2)
119edd5cd4aSDavid Woodhouse {
12057f48b4bSWill Springer loff_t offset = merge_64(offset1, offset2);
12157f48b4bSWill Springer loff_t nbytes = merge_64(nbytes1, nbytes2);
122edd5cd4aSDavid Woodhouse
123806cbae1SDominik Brodowski return ksys_sync_file_range(fd, offset, nbytes, flags);
124edd5cd4aSDavid Woodhouse }
125*ce883a2bSAndreas Schwab
126*ce883a2bSAndreas Schwab #ifdef CONFIG_PPC32
SYSCALL_DEFINE6(ppc_fallocate,int,fd,int,mode,u32,offset1,u32,offset2,u32,len1,u32,len2)127*ce883a2bSAndreas Schwab SYSCALL_DEFINE6(ppc_fallocate,
128*ce883a2bSAndreas Schwab int, fd, int, mode,
129*ce883a2bSAndreas Schwab u32, offset1, u32, offset2, u32, len1, u32, len2)
130*ce883a2bSAndreas Schwab {
131*ce883a2bSAndreas Schwab return ksys_fallocate(fd, mode,
132*ce883a2bSAndreas Schwab merge_64(offset1, offset2),
133*ce883a2bSAndreas Schwab merge_64(len1, len2));
134*ce883a2bSAndreas Schwab }
135*ce883a2bSAndreas Schwab #endif
136