at v3.3-rc7 161 lines 4.6 kB view raw
1/* 2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 */ 14 15/* Adjust unistd.h to provide 32-bit numbers and functions. */ 16#define __SYSCALL_COMPAT 17 18#include <linux/compat.h> 19#include <linux/msg.h> 20#include <linux/syscalls.h> 21#include <linux/kdev_t.h> 22#include <linux/fs.h> 23#include <linux/fcntl.h> 24#include <linux/uaccess.h> 25#include <linux/signal.h> 26#include <asm/syscalls.h> 27 28/* 29 * Syscalls that take 64-bit numbers traditionally take them in 32-bit 30 * "high" and "low" value parts on 32-bit architectures. 31 * In principle, one could imagine passing some register arguments as 32 * fully 64-bit on TILE-Gx in 32-bit mode, but it seems easier to 33 * adapt the usual convention. 34 */ 35 36long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high) 37{ 38 return sys_truncate(filename, ((loff_t)high << 32) | low); 39} 40 41long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high) 42{ 43 return sys_ftruncate(fd, ((loff_t)high << 32) | low); 44} 45 46long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count, 47 u32 dummy, u32 low, u32 high) 48{ 49 return sys_pread64(fd, ubuf, count, ((loff_t)high << 32) | low); 50} 51 52long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count, 53 u32 dummy, u32 low, u32 high) 54{ 55 return sys_pwrite64(fd, ubuf, count, ((loff_t)high << 32) | low); 56} 57 58long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len) 59{ 60 return sys_lookup_dcookie(((loff_t)high << 32) | low, buf, len); 61} 62 63long compat_sys_sync_file_range2(int fd, unsigned int flags, 64 u32 offset_lo, u32 offset_hi, 65 u32 nbytes_lo, u32 nbytes_hi) 66{ 67 return sys_sync_file_range(fd, ((loff_t)offset_hi << 32) | offset_lo, 68 ((loff_t)nbytes_hi << 32) | nbytes_lo, 69 flags); 70} 71 72long compat_sys_fallocate(int fd, int mode, 73 u32 offset_lo, u32 offset_hi, 74 u32 len_lo, u32 len_hi) 75{ 76 return sys_fallocate(fd, mode, ((loff_t)offset_hi << 32) | offset_lo, 77 ((loff_t)len_hi << 32) | len_lo); 78} 79 80 81 82long compat_sys_sched_rr_get_interval(compat_pid_t pid, 83 struct compat_timespec __user *interval) 84{ 85 struct timespec t; 86 int ret; 87 mm_segment_t old_fs = get_fs(); 88 89 set_fs(KERNEL_DS); 90 ret = sys_sched_rr_get_interval(pid, 91 (struct timespec __force __user *)&t); 92 set_fs(old_fs); 93 if (put_compat_timespec(&t, interval)) 94 return -EFAULT; 95 return ret; 96} 97 98/* 99 * The usual compat_sys_msgsnd() and _msgrcv() seem to be assuming 100 * some different calling convention than our normal 32-bit tile code. 101 */ 102 103/* Already defined in ipc/compat.c, but we need it here. */ 104struct compat_msgbuf { 105 compat_long_t mtype; 106 char mtext[1]; 107}; 108 109long tile_compat_sys_msgsnd(int msqid, 110 struct compat_msgbuf __user *msgp, 111 size_t msgsz, int msgflg) 112{ 113 compat_long_t mtype; 114 115 if (get_user(mtype, &msgp->mtype)) 116 return -EFAULT; 117 return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); 118} 119 120long tile_compat_sys_msgrcv(int msqid, 121 struct compat_msgbuf __user *msgp, 122 size_t msgsz, long msgtyp, int msgflg) 123{ 124 long err, mtype; 125 126 err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg); 127 if (err < 0) 128 goto out; 129 130 if (put_user(mtype, &msgp->mtype)) 131 err = -EFAULT; 132 out: 133 return err; 134} 135 136/* Provide the compat syscall number to call mapping. */ 137#undef __SYSCALL 138#define __SYSCALL(nr, call) [nr] = (call), 139 140/* The generic versions of these don't work for Tile. */ 141#define compat_sys_msgrcv tile_compat_sys_msgrcv 142#define compat_sys_msgsnd tile_compat_sys_msgsnd 143 144/* See comments in sys.c */ 145#define compat_sys_fadvise64_64 sys32_fadvise64_64 146#define compat_sys_readahead sys32_readahead 147 148/* Call the trampolines to manage pt_regs where necessary. */ 149#define compat_sys_execve _compat_sys_execve 150#define compat_sys_sigaltstack _compat_sys_sigaltstack 151#define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn 152#define sys_clone _sys_clone 153 154/* 155 * Note that we can't include <linux/unistd.h> here since the header 156 * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well. 157 */ 158void *compat_sys_call_table[__NR_syscalls] = { 159 [0 ... __NR_syscalls-1] = sys_ni_syscall, 160#include <asm/unistd.h> 161};