1/* 2 * linux/arch/x86_64/kernel/sys_x86_64.c 3 */ 4 5#include <linux/errno.h> 6#include <linux/sched.h> 7#include <linux/mm.h> 8#include <linux/smp.h> 9#include <linux/smp_lock.h> 10#include <linux/sem.h> 11#include <linux/msg.h> 12#include <linux/shm.h> 13#include <linux/stat.h> 14#include <linux/mman.h> 15#include <linux/file.h> 16#include <linux/utsname.h> 17#include <linux/personality.h> 18 19#include <asm/uaccess.h> 20#include <asm/ipc.h> 21 22/* 23 * sys_pipe() is the normal C calling standard for creating 24 * a pipe. It's not the way Unix traditionally does this, though. 25 */ 26asmlinkage long sys_pipe(unsigned long * fildes) 27{ 28 int fd[2]; 29 int error; 30 31 error = do_pipe(fd); 32 if (!error) { 33 if (copy_to_user(fildes, fd, 2*sizeof(int))) 34 error = -EFAULT; 35 } 36 return error; 37} 38 39long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, 40 unsigned long fd, unsigned long off) 41{ 42 long error; 43 struct file * file; 44 45 error = -EINVAL; 46 if (off & ~PAGE_MASK) 47 goto out; 48 49 error = -EBADF; 50 file = NULL; 51 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 52 if (!(flags & MAP_ANONYMOUS)) { 53 file = fget(fd); 54 if (!file) 55 goto out; 56 } 57 58 down_write(¤t->mm->mmap_sem); 59 error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT); 60 up_write(¤t->mm->mmap_sem); 61 62 if (file) 63 fput(file); 64out: 65 return error; 66} 67 68unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) 69{ 70 struct vm_area_struct *vma; 71 unsigned long end = TASK_SIZE; 72 73 if (current->thread.flags & THREAD_IA32) 74 flags |= MAP_32BIT; 75 if (flags & MAP_32BIT) 76 end = 0xffffffff-1; 77 if (len > end) 78 return -ENOMEM; 79 if (!addr) { 80 addr = TASK_UNMAPPED_64; 81 if (flags & MAP_32BIT) { 82 addr = TASK_UNMAPPED_32; 83 } 84 } 85 addr = PAGE_ALIGN(addr); 86 87 for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { 88 /* At this point: (!vma || addr < vma->vm_end). */ 89 if (end - len < addr) 90 return -ENOMEM; 91 if (!vma || addr + len <= vma->vm_start) 92 return addr; 93 addr = vma->vm_end; 94 } 95} 96 97asmlinkage long sys_uname(struct new_utsname * name) 98{ 99 int err; 100 down_read(&uts_sem); 101 err=copy_to_user(name, &system_utsname, sizeof (*name)); 102 up_read(&uts_sem); 103 if (personality(current->personality) == PER_LINUX32) 104 err = copy_to_user(name->machine, "i686", 5); 105 return err?-EFAULT:0; 106} 107 108asmlinkage long sys_pause(void) 109{ 110 current->state = TASK_INTERRUPTIBLE; 111 schedule(); 112 return -ERESTARTNOHAND; 113} 114 115asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg) 116{ 117 unsigned long raddr; 118 return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: raddr; 119} 120