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, arg2: (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, pgoff: off >> PAGE_SHIFT); |
64 | } |
65 | |