1 /* 2 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Copyright 2003 PathScale, Inc. 4 * 5 * Licensed under the GPL 6 */ 7 8 #include <linux/sched.h> 9 #include <linux/sched/mm.h> 10 #include <linux/syscalls.h> 11 #include <linux/uaccess.h> 12 #include <asm/prctl.h> /* XXX This should get the constants from libc */ 13 #include <registers.h> 14 #include <os.h> 15 16 long arch_prctl(struct task_struct *task, int option, 17 unsigned long __user *arg2) 18 { 19 long ret = -EINVAL; 20 21 switch (option) { 22 case ARCH_SET_FS: 23 current->thread.regs.regs.gp[FS_BASE / sizeof(unsigned long)] = 24 (unsigned long) arg2; 25 ret = 0; 26 break; 27 case ARCH_SET_GS: 28 current->thread.regs.regs.gp[GS_BASE / sizeof(unsigned long)] = 29 (unsigned long) arg2; 30 ret = 0; 31 break; 32 case ARCH_GET_FS: 33 ret = put_user(current->thread.regs.regs.gp[FS_BASE / sizeof(unsigned long)], arg2); 34 break; 35 case ARCH_GET_GS: 36 ret = put_user(current->thread.regs.regs.gp[GS_BASE / sizeof(unsigned long)], arg2); 37 break; 38 } 39 40 return ret; 41 } 42 43 SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) 44 { 45 return arch_prctl(current, option, (unsigned long __user *) arg2); 46 } 47 48 void arch_switch_to(struct task_struct *to) 49 { 50 /* 51 * Nothing needs to be done on x86_64. 52 * The FS_BASE/GS_BASE registers are saved in the ptrace register set. 53 */ 54 } 55 56 SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, 57 unsigned long, prot, unsigned long, flags, 58 unsigned long, fd, unsigned long, off) 59 { 60 if (off & ~PAGE_MASK) 61 return -EINVAL; 62 63 return ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); 64 } 65