diff options
Diffstat (limited to 'arch/um/include/sysdep-i386')
-rw-r--r-- | arch/um/include/sysdep-i386/checksum.h | 39 | ||||
-rw-r--r-- | arch/um/include/sysdep-i386/faultinfo.h | 29 | ||||
-rw-r--r-- | arch/um/include/sysdep-i386/ptrace.h | 26 | ||||
-rw-r--r-- | arch/um/include/sysdep-i386/sigcontext.h | 19 | ||||
-rw-r--r-- | arch/um/include/sysdep-i386/signal.h | 2 | ||||
-rw-r--r-- | arch/um/include/sysdep-i386/skas_ptrace.h | 22 |
6 files changed, 88 insertions, 49 deletions
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h index 3a2a45811aa3..764ba4db4788 100644 --- a/arch/um/include/sysdep-i386/checksum.h +++ b/arch/um/include/sysdep-i386/checksum.h | |||
@@ -24,19 +24,6 @@ unsigned int csum_partial(const unsigned char * buff, int len, | |||
24 | unsigned int sum); | 24 | unsigned int sum); |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * the same as csum_partial, but copies from src while it | ||
28 | * checksums, and handles user-space pointer exceptions correctly, when needed. | ||
29 | * | ||
30 | * here even more important to align src and dst on a 32-bit (or even | ||
31 | * better 64-bit) boundary | ||
32 | */ | ||
33 | |||
34 | unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst, | ||
35 | int len, int sum, int *err_ptr); | ||
36 | unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, | ||
37 | int len, int sum, int *err_ptr); | ||
38 | |||
39 | /* | ||
40 | * Note: when you get a NULL pointer exception here this means someone | 27 | * Note: when you get a NULL pointer exception here this means someone |
41 | * passed in an incorrect kernel address to one of these functions. | 28 | * passed in an incorrect kernel address to one of these functions. |
42 | * | 29 | * |
@@ -52,11 +39,24 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * | |||
52 | return(csum_partial(dst, len, sum)); | 39 | return(csum_partial(dst, len, sum)); |
53 | } | 40 | } |
54 | 41 | ||
42 | /* | ||
43 | * the same as csum_partial, but copies from src while it | ||
44 | * checksums, and handles user-space pointer exceptions correctly, when needed. | ||
45 | * | ||
46 | * here even more important to align src and dst on a 32-bit (or even | ||
47 | * better 64-bit) boundary | ||
48 | */ | ||
49 | |||
55 | static __inline__ | 50 | static __inline__ |
56 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, | 51 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, |
57 | int len, int sum, int *err_ptr) | 52 | int len, int sum, int *err_ptr) |
58 | { | 53 | { |
59 | return csum_partial_copy_from(src, dst, len, sum, err_ptr); | 54 | if(copy_from_user(dst, src, len)){ |
55 | *err_ptr = -EFAULT; | ||
56 | return(-1); | ||
57 | } | ||
58 | |||
59 | return csum_partial(dst, len, sum); | ||
60 | } | 60 | } |
61 | 61 | ||
62 | /* | 62 | /* |
@@ -67,7 +67,6 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char | |||
67 | */ | 67 | */ |
68 | 68 | ||
69 | #define csum_partial_copy_fromuser csum_partial_copy_from_user | 69 | #define csum_partial_copy_fromuser csum_partial_copy_from_user |
70 | unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum); | ||
71 | 70 | ||
72 | /* | 71 | /* |
73 | * This is a version of ip_compute_csum() optimized for IP headers, | 72 | * This is a version of ip_compute_csum() optimized for IP headers, |
@@ -196,8 +195,14 @@ static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, | |||
196 | unsigned char *dst, | 195 | unsigned char *dst, |
197 | int len, int sum, int *err_ptr) | 196 | int len, int sum, int *err_ptr) |
198 | { | 197 | { |
199 | if (access_ok(VERIFY_WRITE, dst, len)) | 198 | if (access_ok(VERIFY_WRITE, dst, len)){ |
200 | return(csum_partial_copy_to(src, dst, len, sum, err_ptr)); | 199 | if(copy_to_user(dst, src, len)){ |
200 | *err_ptr = -EFAULT; | ||
201 | return(-1); | ||
202 | } | ||
203 | |||
204 | return csum_partial(src, len, sum); | ||
205 | } | ||
201 | 206 | ||
202 | if (len) | 207 | if (len) |
203 | *err_ptr = -EFAULT; | 208 | *err_ptr = -EFAULT; |
diff --git a/arch/um/include/sysdep-i386/faultinfo.h b/arch/um/include/sysdep-i386/faultinfo.h new file mode 100644 index 000000000000..db437cc373bc --- /dev/null +++ b/arch/um/include/sysdep-i386/faultinfo.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Fujitsu Siemens Computers GmbH | ||
3 | * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> | ||
4 | * Licensed under the GPL | ||
5 | */ | ||
6 | |||
7 | #ifndef __FAULTINFO_I386_H | ||
8 | #define __FAULTINFO_I386_H | ||
9 | |||
10 | /* this structure contains the full arch-specific faultinfo | ||
11 | * from the traps. | ||
12 | * On i386, ptrace_faultinfo unfortunately doesn't provide | ||
13 | * all the info, since trap_no is missing. | ||
14 | * All common elements are defined at the same position in | ||
15 | * both structures, thus making it easy to copy the | ||
16 | * contents without knowledge about the structure elements. | ||
17 | */ | ||
18 | struct faultinfo { | ||
19 | int error_code; /* in ptrace_faultinfo misleadingly called is_write */ | ||
20 | unsigned long cr2; /* in ptrace_faultinfo called addr */ | ||
21 | int trap_no; /* missing in ptrace_faultinfo */ | ||
22 | }; | ||
23 | |||
24 | #define FAULT_WRITE(fi) ((fi).error_code & 2) | ||
25 | #define FAULT_ADDRESS(fi) ((fi).cr2) | ||
26 | |||
27 | #define PTRACE_FULL_FAULTINFO 0 | ||
28 | |||
29 | #endif | ||
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h index 661d495e2044..c8ee9559f3ab 100644 --- a/arch/um/include/sysdep-i386/ptrace.h +++ b/arch/um/include/sysdep-i386/ptrace.h | |||
@@ -8,6 +8,8 @@ | |||
8 | 8 | ||
9 | #include "uml-config.h" | 9 | #include "uml-config.h" |
10 | #include "user_constants.h" | 10 | #include "user_constants.h" |
11 | #include "sysdep/faultinfo.h" | ||
12 | #include "choose-mode.h" | ||
11 | 13 | ||
12 | #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) | 14 | #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) |
13 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) | 15 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) |
@@ -53,24 +55,17 @@ extern int sysemu_supported; | |||
53 | 55 | ||
54 | #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) | 56 | #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) |
55 | 57 | ||
56 | #define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type) | ||
57 | |||
58 | #define REGS_FAULT_ADDR(r) ((r)->fault_addr) | ||
59 | |||
60 | #define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) | ||
61 | |||
62 | #endif | 58 | #endif |
63 | #ifndef PTRACE_SYSEMU_SINGLESTEP | 59 | #ifndef PTRACE_SYSEMU_SINGLESTEP |
64 | #define PTRACE_SYSEMU_SINGLESTEP 32 | 60 | #define PTRACE_SYSEMU_SINGLESTEP 32 |
65 | #endif | 61 | #endif |
66 | 62 | ||
67 | #include "choose-mode.h" | ||
68 | |||
69 | union uml_pt_regs { | 63 | union uml_pt_regs { |
70 | #ifdef UML_CONFIG_MODE_TT | 64 | #ifdef UML_CONFIG_MODE_TT |
71 | struct tt_regs { | 65 | struct tt_regs { |
72 | long syscall; | 66 | long syscall; |
73 | void *sc; | 67 | void *sc; |
68 | struct faultinfo faultinfo; | ||
74 | } tt; | 69 | } tt; |
75 | #endif | 70 | #endif |
76 | #ifdef UML_CONFIG_MODE_SKAS | 71 | #ifdef UML_CONFIG_MODE_SKAS |
@@ -78,9 +73,7 @@ union uml_pt_regs { | |||
78 | unsigned long regs[HOST_FRAME_SIZE]; | 73 | unsigned long regs[HOST_FRAME_SIZE]; |
79 | unsigned long fp[HOST_FP_SIZE]; | 74 | unsigned long fp[HOST_FP_SIZE]; |
80 | unsigned long xfp[HOST_XFP_SIZE]; | 75 | unsigned long xfp[HOST_XFP_SIZE]; |
81 | unsigned long fault_addr; | 76 | struct faultinfo faultinfo; |
82 | unsigned long fault_type; | ||
83 | unsigned long trap_type; | ||
84 | long syscall; | 77 | long syscall; |
85 | int is_user; | 78 | int is_user; |
86 | } skas; | 79 | } skas; |
@@ -217,15 +210,8 @@ struct syscall_args { | |||
217 | #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) | 210 | #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) |
218 | #define UPT_SYSCALL_RET(r) UPT_EAX(r) | 211 | #define UPT_SYSCALL_RET(r) UPT_EAX(r) |
219 | 212 | ||
220 | #define UPT_SEGV_IS_FIXABLE(r) \ | 213 | #define UPT_FAULTINFO(r) \ |
221 | CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ | 214 | CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo)) |
222 | REGS_SEGV_IS_FIXABLE(&r->skas)) | ||
223 | |||
224 | #define UPT_FAULT_ADDR(r) \ | ||
225 | __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) | ||
226 | |||
227 | #define UPT_FAULT_WRITE(r) \ | ||
228 | CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas)) | ||
229 | 215 | ||
230 | #endif | 216 | #endif |
231 | 217 | ||
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h index dfee589de360..1fe729265167 100644 --- a/arch/um/include/sysdep-i386/sigcontext.h +++ b/arch/um/include/sysdep-i386/sigcontext.h | |||
@@ -13,15 +13,12 @@ | |||
13 | #define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) | 13 | #define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) |
14 | #define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) | 14 | #define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) |
15 | 15 | ||
16 | #define SC_FAULT_ADDR(sc) SC_CR2(sc) | 16 | #define GET_FAULTINFO_FROM_SC(fi,sc) \ |
17 | #define SC_FAULT_TYPE(sc) SC_ERR(sc) | 17 | { \ |
18 | 18 | (fi).cr2 = SC_CR2(sc); \ | |
19 | #define FAULT_WRITE(err) (err & 2) | 19 | (fi).error_code = SC_ERR(sc); \ |
20 | #define TO_SC_ERR(is_write) ((is_write) ? 2 : 0) | 20 | (fi).trap_no = SC_TRAPNO(sc); \ |
21 | 21 | } | |
22 | #define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc))) | ||
23 | |||
24 | #define SC_TRAP_TYPE(sc) SC_TRAPNO(sc) | ||
25 | 22 | ||
26 | /* ptrace expects that, at the start of a system call, %eax contains | 23 | /* ptrace expects that, at the start of a system call, %eax contains |
27 | * -ENOSYS, so this makes it so. | 24 | * -ENOSYS, so this makes it so. |
@@ -29,9 +26,7 @@ | |||
29 | #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) | 26 | #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) |
30 | 27 | ||
31 | /* This is Page Fault */ | 28 | /* This is Page Fault */ |
32 | #define SEGV_IS_FIXABLE(trap) (trap == 14) | 29 | #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) |
33 | |||
34 | #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc))) | ||
35 | 30 | ||
36 | extern unsigned long *sc_sigmask(void *sc_ptr); | 31 | extern unsigned long *sc_sigmask(void *sc_ptr); |
37 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); | 32 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); |
diff --git a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h index b1e1f7a77499..07518b162136 100644 --- a/arch/um/include/sysdep-i386/signal.h +++ b/arch/um/include/sysdep-i386/signal.h | |||
@@ -8,6 +8,8 @@ | |||
8 | 8 | ||
9 | #include <signal.h> | 9 | #include <signal.h> |
10 | 10 | ||
11 | #define ARCH_SIGHDLR_PARAM int sig | ||
12 | |||
11 | #define ARCH_GET_SIGCONTEXT(sc, sig) \ | 13 | #define ARCH_GET_SIGCONTEXT(sc, sig) \ |
12 | do sc = (struct sigcontext *) (&sig + 1); while(0) | 14 | do sc = (struct sigcontext *) (&sig + 1); while(0) |
13 | 15 | ||
diff --git a/arch/um/include/sysdep-i386/skas_ptrace.h b/arch/um/include/sysdep-i386/skas_ptrace.h new file mode 100644 index 000000000000..e27b8a791773 --- /dev/null +++ b/arch/um/include/sysdep-i386/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_I386_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_I386_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||