Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * sys_ppc32.c: Conversion between 32bit and 64bit native syscalls.
0004  *
0005  * Copyright (C) 2001 IBM
0006  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
0007  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
0008  *
0009  * These routines maintain argument size conversion between 32bit and 64bit
0010  * environment.
0011  */
0012 
0013 #include <linux/kernel.h>
0014 #include <linux/sched.h>
0015 #include <linux/fs.h> 
0016 #include <linux/mm.h> 
0017 #include <linux/file.h> 
0018 #include <linux/signal.h>
0019 #include <linux/resource.h>
0020 #include <linux/times.h>
0021 #include <linux/smp.h>
0022 #include <linux/sem.h>
0023 #include <linux/msg.h>
0024 #include <linux/shm.h>
0025 #include <linux/poll.h>
0026 #include <linux/personality.h>
0027 #include <linux/stat.h>
0028 #include <linux/mman.h>
0029 #include <linux/in.h>
0030 #include <linux/syscalls.h>
0031 #include <linux/unistd.h>
0032 #include <linux/sysctl.h>
0033 #include <linux/binfmts.h>
0034 #include <linux/security.h>
0035 #include <linux/compat.h>
0036 #include <linux/ptrace.h>
0037 #include <linux/elf.h>
0038 #include <linux/ipc.h>
0039 #include <linux/slab.h>
0040 
0041 #include <asm/ptrace.h>
0042 #include <asm/types.h>
0043 #include <linux/uaccess.h>
0044 #include <asm/unistd.h>
0045 #include <asm/time.h>
0046 #include <asm/mmu_context.h>
0047 #include <asm/ppc-pci.h>
0048 #include <asm/syscalls.h>
0049 #include <asm/switch_to.h>
0050 
0051 unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
0052               unsigned long prot, unsigned long flags,
0053               unsigned long fd, unsigned long pgoff)
0054 {
0055     /* This should remain 12 even if PAGE_SIZE changes */
0056     return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
0057 }
0058 
0059 /* 
0060  * long long munging:
0061  * The 32 bit ABI passes long longs in an odd even register pair.
0062  * High and low parts are swapped depending on endian mode,
0063  * so define a macro (similar to mips linux32) to handle that.
0064  */
0065 #ifdef __LITTLE_ENDIAN__
0066 #define merge_64(low, high) ((u64)high << 32) | low
0067 #else
0068 #define merge_64(high, low) ((u64)high << 32) | low
0069 #endif
0070 
0071 compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
0072                  u32 reg6, u32 pos1, u32 pos2)
0073 {
0074     return ksys_pread64(fd, ubuf, count, merge_64(pos1, pos2));
0075 }
0076 
0077 compat_ssize_t compat_sys_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count,
0078                   u32 reg6, u32 pos1, u32 pos2)
0079 {
0080     return ksys_pwrite64(fd, ubuf, count, merge_64(pos1, pos2));
0081 }
0082 
0083 compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offset1, u32 offset2, u32 count)
0084 {
0085     return ksys_readahead(fd, merge_64(offset1, offset2), count);
0086 }
0087 
0088 asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,
0089                 unsigned long len1, unsigned long len2)
0090 {
0091     return ksys_truncate(path, merge_64(len1, len2));
0092 }
0093 
0094 asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offset1, u32 offset2,
0095                      u32 len1, u32 len2)
0096 {
0097     return ksys_fallocate(fd, mode, ((loff_t)offset1 << 32) | offset2,
0098                  merge_64(len1, len2));
0099 }
0100 
0101 asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long len1,
0102                  unsigned long len2)
0103 {
0104     return ksys_ftruncate(fd, merge_64(len1, len2));
0105 }
0106 
0107 long ppc32_fadvise64(int fd, u32 unused, u32 offset1, u32 offset2,
0108              size_t len, int advice)
0109 {
0110     return ksys_fadvise64_64(fd, merge_64(offset1, offset2), len,
0111                  advice);
0112 }
0113 
0114 asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags,
0115                    unsigned offset1, unsigned offset2,
0116                    unsigned nbytes1, unsigned nbytes2)
0117 {
0118     loff_t offset = merge_64(offset1, offset2);
0119     loff_t nbytes = merge_64(nbytes1, nbytes2);
0120 
0121     return ksys_sync_file_range(fd, offset, nbytes, flags);
0122 }