diff options
-rw-r--r-- | arch/um/include/ptrace_user.h | 11 | ||||
-rw-r--r-- | arch/um/sys-i386/ptrace_user.c | 14 | ||||
-rw-r--r-- | arch/um/sys-x86_64/bug.c | 3 | ||||
-rw-r--r-- | arch/um/sys-x86_64/ptrace.c | 29 | ||||
-rw-r--r-- | arch/um/sys-x86_64/ptrace_user.c | 46 | ||||
-rw-r--r-- | arch/um/sys-x86_64/syscall_table.c | 31 | ||||
-rw-r--r-- | arch/um/sys-x86_64/sysrq.c | 29 | ||||
-rw-r--r-- | arch/um/sys-x86_64/um_module.c | 8 |
8 files changed, 65 insertions, 106 deletions
diff --git a/arch/um/include/ptrace_user.h b/arch/um/include/ptrace_user.h index f3450e6bc18d..4bce6e012889 100644 --- a/arch/um/include/ptrace_user.h +++ b/arch/um/include/ptrace_user.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -10,12 +10,6 @@ | |||
10 | 10 | ||
11 | extern int ptrace_getregs(long pid, unsigned long *regs_out); | 11 | extern int ptrace_getregs(long pid, unsigned long *regs_out); |
12 | extern int ptrace_setregs(long pid, unsigned long *regs_in); | 12 | extern int ptrace_setregs(long pid, unsigned long *regs_in); |
13 | extern int ptrace_getfpregs(long pid, unsigned long *regs_out); | ||
14 | extern int ptrace_setfpregs(long pid, unsigned long *regs); | ||
15 | extern void arch_enter_kernel(void *task, int pid); | ||
16 | extern void arch_leave_kernel(void *task, int pid); | ||
17 | extern void ptrace_pokeuser(unsigned long addr, unsigned long data); | ||
18 | |||
19 | 13 | ||
20 | /* syscall emulation path in ptrace */ | 14 | /* syscall emulation path in ptrace */ |
21 | 15 | ||
@@ -54,7 +48,8 @@ extern int sysemu_supported; | |||
54 | (((int[3][3] ) { \ | 48 | (((int[3][3] ) { \ |
55 | { PTRACE_SYSCALL, PTRACE_SYSCALL, PTRACE_SINGLESTEP }, \ | 49 | { PTRACE_SYSCALL, PTRACE_SYSCALL, PTRACE_SINGLESTEP }, \ |
56 | { PTRACE_SYSEMU, PTRACE_SYSEMU, PTRACE_SINGLESTEP }, \ | 50 | { PTRACE_SYSEMU, PTRACE_SYSEMU, PTRACE_SINGLESTEP }, \ |
57 | { PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP, PTRACE_SYSEMU_SINGLESTEP }}) \ | 51 | { PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP, \ |
52 | PTRACE_SYSEMU_SINGLESTEP } }) \ | ||
58 | [sysemu_mode][singlestep_mode]) | 53 | [sysemu_mode][singlestep_mode]) |
59 | 54 | ||
60 | #endif | 55 | #endif |
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 5cf97bc229b9..0b10c3e74028 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c | |||
@@ -19,17 +19,3 @@ int ptrace_setregs(long pid, unsigned long *regs) | |||
19 | return -errno; | 19 | return -errno; |
20 | return 0; | 20 | return 0; |
21 | } | 21 | } |
22 | |||
23 | int ptrace_getfpregs(long pid, unsigned long *regs) | ||
24 | { | ||
25 | if (ptrace(PTRACE_GETFPREGS, pid, 0, regs) < 0) | ||
26 | return -errno; | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | int ptrace_setfpregs(long pid, unsigned long *regs) | ||
31 | { | ||
32 | if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0) | ||
33 | return -errno; | ||
34 | return 0; | ||
35 | } | ||
diff --git a/arch/um/sys-x86_64/bug.c b/arch/um/sys-x86_64/bug.c index a4360b5207db..e8034e363d83 100644 --- a/arch/um/sys-x86_64/bug.c +++ b/arch/um/sys-x86_64/bug.c | |||
@@ -5,7 +5,8 @@ | |||
5 | 5 | ||
6 | #include <linux/uaccess.h> | 6 | #include <linux/uaccess.h> |
7 | 7 | ||
8 | /* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because | 8 | /* |
9 | * Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because | ||
9 | * that's not relevant in skas mode. | 10 | * that's not relevant in skas mode. |
10 | */ | 11 | */ |
11 | 12 | ||
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index b7631b0e9ddc..f3458d7d1c5a 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c | |||
@@ -5,13 +5,12 @@ | |||
5 | * Licensed under the GPL | 5 | * Licensed under the GPL |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define __FRAME_OFFSETS | 8 | #include <linux/mm.h> |
9 | #include <asm/ptrace.h> | ||
10 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
11 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
12 | #include <linux/mm.h> | 11 | #define __FRAME_OFFSETS |
12 | #include <asm/ptrace.h> | ||
13 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
14 | #include <asm/elf.h> | ||
15 | 14 | ||
16 | /* | 15 | /* |
17 | * determines which flags the user has access to. | 16 | * determines which flags the user has access to. |
@@ -24,12 +23,14 @@ int putreg(struct task_struct *child, int regno, unsigned long value) | |||
24 | unsigned long tmp; | 23 | unsigned long tmp; |
25 | 24 | ||
26 | #ifdef TIF_IA32 | 25 | #ifdef TIF_IA32 |
27 | /* Some code in the 64bit emulation may not be 64bit clean. | 26 | /* |
28 | Don't take any chances. */ | 27 | * Some code in the 64bit emulation may not be 64bit clean. |
28 | * Don't take any chances. | ||
29 | */ | ||
29 | if (test_tsk_thread_flag(child, TIF_IA32)) | 30 | if (test_tsk_thread_flag(child, TIF_IA32)) |
30 | value &= 0xffffffff; | 31 | value &= 0xffffffff; |
31 | #endif | 32 | #endif |
32 | switch (regno){ | 33 | switch (regno) { |
33 | case FS: | 34 | case FS: |
34 | case GS: | 35 | case GS: |
35 | case DS: | 36 | case DS: |
@@ -66,7 +67,7 @@ int poke_user(struct task_struct *child, long addr, long data) | |||
66 | if (addr < MAX_REG_OFFSET) | 67 | if (addr < MAX_REG_OFFSET) |
67 | return putreg(child, addr, data); | 68 | return putreg(child, addr, data); |
68 | else if ((addr >= offsetof(struct user, u_debugreg[0])) && | 69 | else if ((addr >= offsetof(struct user, u_debugreg[0])) && |
69 | (addr <= offsetof(struct user, u_debugreg[7]))){ | 70 | (addr <= offsetof(struct user, u_debugreg[7]))) { |
70 | addr -= offsetof(struct user, u_debugreg[0]); | 71 | addr -= offsetof(struct user, u_debugreg[0]); |
71 | addr = addr >> 2; | 72 | addr = addr >> 2; |
72 | if ((addr == 4) || (addr == 5)) | 73 | if ((addr == 4) || (addr == 5)) |
@@ -108,11 +109,10 @@ int peek_user(struct task_struct *child, long addr, long data) | |||
108 | return -EIO; | 109 | return -EIO; |
109 | 110 | ||
110 | tmp = 0; /* Default return condition */ | 111 | tmp = 0; /* Default return condition */ |
111 | if (addr < MAX_REG_OFFSET){ | 112 | if (addr < MAX_REG_OFFSET) |
112 | tmp = getreg(child, addr); | 113 | tmp = getreg(child, addr); |
113 | } | ||
114 | else if ((addr >= offsetof(struct user, u_debugreg[0])) && | 114 | else if ((addr >= offsetof(struct user, u_debugreg[0])) && |
115 | (addr <= offsetof(struct user, u_debugreg[7]))){ | 115 | (addr <= offsetof(struct user, u_debugreg[7]))) { |
116 | addr -= offsetof(struct user, u_debugreg[0]); | 116 | addr -= offsetof(struct user, u_debugreg[0]); |
117 | addr = addr >> 2; | 117 | addr = addr >> 2; |
118 | tmp = child->thread.arch.debugregs[addr]; | 118 | tmp = child->thread.arch.debugregs[addr]; |
@@ -127,8 +127,9 @@ int is_syscall(unsigned long addr) | |||
127 | int n; | 127 | int n; |
128 | 128 | ||
129 | n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); | 129 | n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); |
130 | if (n){ | 130 | if (n) { |
131 | /* access_process_vm() grants access to vsyscall and stub, | 131 | /* |
132 | * access_process_vm() grants access to vsyscall and stub, | ||
132 | * while copy_from_user doesn't. Maybe access_process_vm is | 133 | * while copy_from_user doesn't. Maybe access_process_vm is |
133 | * slow, but that doesn't matter, since it will be called only | 134 | * slow, but that doesn't matter, since it will be called only |
134 | * in case of singlestepping, if copy_from_user failed. | 135 | * in case of singlestepping, if copy_from_user failed. |
@@ -155,7 +156,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) | |||
155 | return err; | 156 | return err; |
156 | 157 | ||
157 | n = copy_to_user(buf, fpregs, sizeof(fpregs)); | 158 | n = copy_to_user(buf, fpregs, sizeof(fpregs)); |
158 | if(n > 0) | 159 | if (n > 0) |
159 | return -EFAULT; | 160 | return -EFAULT; |
160 | 161 | ||
161 | return n; | 162 | return n; |
diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c index b5f9c33e311e..c57a496d3f5b 100644 --- a/arch/um/sys-x86_64/ptrace_user.c +++ b/arch/um/sys-x86_64/ptrace_user.c | |||
@@ -4,55 +4,19 @@ | |||
4 | * Licensed under the GPL | 4 | * Licensed under the GPL |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <stddef.h> | ||
8 | #include <errno.h> | 7 | #include <errno.h> |
9 | #include "ptrace_user.h" | 8 | #include "ptrace_user.h" |
10 | #include "user.h" | ||
11 | #include "kern_constants.h" | ||
12 | 9 | ||
13 | int ptrace_getregs(long pid, unsigned long *regs_out) | 10 | int ptrace_getregs(long pid, unsigned long *regs_out) |
14 | { | 11 | { |
15 | if(ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) | 12 | if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) |
16 | return(-errno); | 13 | return -errno; |
17 | return(0); | ||
18 | } | ||
19 | |||
20 | int ptrace_setregs(long pid, unsigned long *regs) | ||
21 | { | ||
22 | if(ptrace(PTRACE_SETREGS, pid, 0, regs) < 0) | ||
23 | return(-errno); | ||
24 | return(0); | 14 | return(0); |
25 | } | 15 | } |
26 | 16 | ||
27 | int ptrace_setfpregs(long pid, unsigned long *regs) | 17 | int ptrace_setregs(long pid, unsigned long *regs_out) |
28 | { | 18 | { |
29 | if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0) | 19 | if (ptrace(PTRACE_SETREGS, pid, 0, regs_out) < 0) |
30 | return -errno; | 20 | return -errno; |
31 | return 0; | 21 | return(0); |
32 | } | ||
33 | |||
34 | void ptrace_pokeuser(unsigned long addr, unsigned long data) | ||
35 | { | ||
36 | panic("ptrace_pokeuser"); | ||
37 | } | ||
38 | |||
39 | #define DS 184 | ||
40 | #define ES 192 | ||
41 | #define __USER_DS 0x2b | ||
42 | |||
43 | void arch_enter_kernel(void *task, int pid) | ||
44 | { | ||
45 | } | ||
46 | |||
47 | void arch_leave_kernel(void *task, int pid) | ||
48 | { | ||
49 | #ifdef UM_USER_CS | ||
50 | if(ptrace(PTRACE_POKEUSR, pid, CS, UM_USER_CS) < 0) | ||
51 | printk("POKEUSR CS failed"); | ||
52 | #endif | ||
53 | |||
54 | if(ptrace(PTRACE_POKEUSR, pid, DS, __USER_DS) < 0) | ||
55 | printk("POKEUSR DS failed"); | ||
56 | if(ptrace(PTRACE_POKEUSR, pid, ES, __USER_DS) < 0) | ||
57 | printk("POKEUSR ES failed"); | ||
58 | } | 22 | } |
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c index 71b2ae4ad5de..555faee0d81f 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/um/sys-x86_64/syscall_table.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c | 1 | /* |
2 | * with some changes for UML. */ | 2 | * System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c |
3 | * with some changes for UML. | ||
4 | */ | ||
3 | 5 | ||
4 | #include <linux/linkage.h> | 6 | #include <linux/linkage.h> |
5 | #include <linux/sys.h> | 7 | #include <linux/sys.h> |
@@ -8,22 +10,26 @@ | |||
8 | 10 | ||
9 | #define __NO_STUBS | 11 | #define __NO_STUBS |
10 | 12 | ||
11 | /* Below you can see, in terms of #define's, the differences between the x86-64 | 13 | /* |
12 | * and the UML syscall table. */ | 14 | * Below you can see, in terms of #define's, the differences between the x86-64 |
15 | * and the UML syscall table. | ||
16 | */ | ||
13 | 17 | ||
14 | /* Not going to be implemented by UML, since we have no hardware. */ | 18 | /* Not going to be implemented by UML, since we have no hardware. */ |
15 | #define stub_iopl sys_ni_syscall | 19 | #define stub_iopl sys_ni_syscall |
16 | #define sys_ioperm sys_ni_syscall | 20 | #define sys_ioperm sys_ni_syscall |
17 | 21 | ||
18 | /* The UML TLS problem. Note that x86_64 does not implement this, so the below | 22 | /* |
19 | * is needed only for the ia32 compatibility. */ | 23 | * The UML TLS problem. Note that x86_64 does not implement this, so the below |
20 | /*#define sys_set_thread_area sys_ni_syscall | 24 | * is needed only for the ia32 compatibility. |
21 | #define sys_get_thread_area sys_ni_syscall*/ | 25 | */ |
22 | 26 | ||
23 | /* On UML we call it this way ("old" means it's not mmap2) */ | 27 | /* On UML we call it this way ("old" means it's not mmap2) */ |
24 | #define sys_mmap old_mmap | 28 | #define sys_mmap old_mmap |
25 | /* On x86-64 sys_uname is actually sys_newuname plus a compatibility trick. | 29 | /* |
26 | * See arch/x86_64/kernel/sys_x86_64.c */ | 30 | * On x86-64 sys_uname is actually sys_newuname plus a compatibility trick. |
31 | * See arch/x86_64/kernel/sys_x86_64.c | ||
32 | */ | ||
27 | #define sys_uname sys_uname64 | 33 | #define sys_uname sys_uname64 |
28 | 34 | ||
29 | #define stub_clone sys_clone | 35 | #define stub_clone sys_clone |
@@ -47,7 +53,10 @@ typedef void (*sys_call_ptr_t)(void); | |||
47 | extern void sys_ni_syscall(void); | 53 | extern void sys_ni_syscall(void); |
48 | 54 | ||
49 | sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = { | 55 | sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = { |
50 | /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ | 56 | /* |
57 | * Smells like a like a compiler bug -- it doesn't work when the & | ||
58 | * below is removed. | ||
59 | */ | ||
51 | [0 ... UM_NR_syscall_max] = &sys_ni_syscall, | 60 | [0 ... UM_NR_syscall_max] = &sys_ni_syscall, |
52 | #include <asm-x86/unistd_64.h> | 61 | #include <asm-x86/unistd_64.h> |
53 | }; | 62 | }; |
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c index 765444031819..f4f82beb3508 100644 --- a/arch/um/sys-x86_64/sysrq.c +++ b/arch/um/sys-x86_64/sysrq.c | |||
@@ -4,32 +4,33 @@ | |||
4 | * Licensed under the GPL | 4 | * Licensed under the GPL |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include "linux/kernel.h" | 7 | #include <linux/kernel.h> |
8 | #include "linux/utsname.h" | 8 | #include <linux/module.h> |
9 | #include "linux/module.h" | 9 | #include <linux/sched.h> |
10 | #include "asm/current.h" | 10 | #include <linux/utsname.h> |
11 | #include "asm/ptrace.h" | 11 | #include <asm/current.h> |
12 | #include <asm/ptrace.h> | ||
12 | #include "sysrq.h" | 13 | #include "sysrq.h" |
13 | 14 | ||
14 | void __show_regs(struct pt_regs * regs) | 15 | void __show_regs(struct pt_regs *regs) |
15 | { | 16 | { |
16 | printk("\n"); | 17 | printk("\n"); |
17 | print_modules(); | 18 | print_modules(); |
18 | printk("Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), | 19 | printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), |
19 | current->comm, print_tainted(), init_utsname()->release); | 20 | current->comm, print_tainted(), init_utsname()->release); |
20 | printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff, | 21 | printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, |
21 | PT_REGS_RIP(regs)); | 22 | PT_REGS_RIP(regs)); |
22 | printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), | 23 | printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), |
23 | PT_REGS_EFLAGS(regs)); | 24 | PT_REGS_EFLAGS(regs)); |
24 | printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", | 25 | printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", |
25 | PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs)); | 26 | PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs)); |
26 | printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", | 27 | printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n", |
27 | PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs)); | 28 | PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs)); |
28 | printk("RBP: %016lx R08: %016lx R09: %016lx\n", | 29 | printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n", |
29 | PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs)); | 30 | PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs)); |
30 | printk("R10: %016lx R11: %016lx R12: %016lx\n", | 31 | printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n", |
31 | PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs)); | 32 | PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs)); |
32 | printk("R13: %016lx R14: %016lx R15: %016lx\n", | 33 | printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", |
33 | PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); | 34 | PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); |
34 | } | 35 | } |
35 | 36 | ||
diff --git a/arch/um/sys-x86_64/um_module.c b/arch/um/sys-x86_64/um_module.c index 8b8eff1bd977..3dead392a415 100644 --- a/arch/um/sys-x86_64/um_module.c +++ b/arch/um/sys-x86_64/um_module.c | |||
@@ -1,7 +1,7 @@ | |||
1 | #include <linux/vmalloc.h> | 1 | #include <linux/vmalloc.h> |
2 | #include <linux/moduleloader.h> | 2 | #include <linux/moduleloader.h> |
3 | 3 | ||
4 | /*Copied from i386 arch/i386/kernel/module.c */ | 4 | /* Copied from i386 arch/i386/kernel/module.c */ |
5 | void *module_alloc(unsigned long size) | 5 | void *module_alloc(unsigned long size) |
6 | { | 6 | { |
7 | if (size == 0) | 7 | if (size == 0) |
@@ -13,7 +13,9 @@ void *module_alloc(unsigned long size) | |||
13 | void module_free(struct module *mod, void *module_region) | 13 | void module_free(struct module *mod, void *module_region) |
14 | { | 14 | { |
15 | vfree(module_region); | 15 | vfree(module_region); |
16 | /* FIXME: If module_region == mod->init_region, trim exception | 16 | /* |
17 | table entries. */ | 17 | * FIXME: If module_region == mod->init_region, trim exception |
18 | * table entries. | ||
19 | */ | ||
18 | } | 20 | } |
19 | 21 | ||