diff options
| author | Jeff Dike <jdike@addtoit.com> | 2005-06-13 18:52:14 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-13 23:58:43 -0400 |
| commit | 98fdffccea6cc3fe9dba32c0fcc310bcb5d71529 (patch) | |
| tree | a103491fdd6e9bec45f408d32c976929a7ecd458 | |
| parent | 36ca1195ad7f760a6af3814cb002bd3a3d4b4db1 (diff) | |
[PATCH] uml: use fork instead of clone
Convert the boot-time host ptrace testing from clone to fork. They were
essentially doing fork anyway. This cleans up the code a bit, and makes
valgrind a bit happier about grinding it.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | arch/um/kernel/process.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 793c77c6ef9c..1b5ef3e96c71 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
| @@ -130,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, | |||
| 130 | return(arg.pid); | 130 | return(arg.pid); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | static int ptrace_child(void *arg) | 133 | static int ptrace_child(void) |
| 134 | { | 134 | { |
| 135 | int ret; | 135 | int ret; |
| 136 | int pid = os_getpid(), ppid = getppid(); | 136 | int pid = os_getpid(), ppid = getppid(); |
| @@ -159,20 +159,16 @@ static int ptrace_child(void *arg) | |||
| 159 | _exit(ret); | 159 | _exit(ret); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | static int start_ptraced_child(void **stack_out) | 162 | static int start_ptraced_child(void) |
| 163 | { | 163 | { |
| 164 | void *stack; | ||
| 165 | unsigned long sp; | ||
| 166 | int pid, n, status; | 164 | int pid, n, status; |
| 167 | 165 | ||
| 168 | stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, | 166 | pid = fork(); |
| 169 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 167 | if(pid == 0) |
| 170 | if(stack == MAP_FAILED) | 168 | ptrace_child(); |
| 171 | panic("check_ptrace : mmap failed, errno = %d", errno); | 169 | |
| 172 | sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); | ||
| 173 | pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); | ||
| 174 | if(pid < 0) | 170 | if(pid < 0) |
| 175 | panic("check_ptrace : clone failed, errno = %d", errno); | 171 | panic("check_ptrace : fork failed, errno = %d", errno); |
| 176 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | 172 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); |
| 177 | if(n < 0) | 173 | if(n < 0) |
| 178 | panic("check_ptrace : wait failed, errno = %d", errno); | 174 | panic("check_ptrace : wait failed, errno = %d", errno); |
| @@ -180,7 +176,6 @@ static int start_ptraced_child(void **stack_out) | |||
| 180 | panic("check_ptrace : expected SIGSTOP, got status = %d", | 176 | panic("check_ptrace : expected SIGSTOP, got status = %d", |
| 181 | status); | 177 | status); |
| 182 | 178 | ||
| 183 | *stack_out = stack; | ||
| 184 | return(pid); | 179 | return(pid); |
| 185 | } | 180 | } |
| 186 | 181 | ||
| @@ -188,12 +183,12 @@ static int start_ptraced_child(void **stack_out) | |||
| 188 | * just avoid using sysemu, not panic, but only if SYSEMU features are broken. | 183 | * just avoid using sysemu, not panic, but only if SYSEMU features are broken. |
| 189 | * So only for SYSEMU features we test mustpanic, while normal host features | 184 | * So only for SYSEMU features we test mustpanic, while normal host features |
| 190 | * must work anyway!*/ | 185 | * must work anyway!*/ |
| 191 | static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) | 186 | static int stop_ptraced_child(int pid, int exitcode, int mustexit) |
| 192 | { | 187 | { |
| 193 | int status, n, ret = 0; | 188 | int status, n, ret = 0; |
| 194 | 189 | ||
| 195 | if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) | 190 | if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) |
| 196 | panic("check_ptrace : ptrace failed, errno = %d", errno); | 191 | panic("stop_ptraced_child : ptrace failed, errno = %d", errno); |
| 197 | CATCH_EINTR(n = waitpid(pid, &status, 0)); | 192 | CATCH_EINTR(n = waitpid(pid, &status, 0)); |
| 198 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { | 193 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { |
| 199 | int exit_with = WEXITSTATUS(status); | 194 | int exit_with = WEXITSTATUS(status); |
| @@ -204,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) | |||
| 204 | printk("check_ptrace : child exited with exitcode %d, while " | 199 | printk("check_ptrace : child exited with exitcode %d, while " |
| 205 | "expecting %d; status 0x%x", exit_with, | 200 | "expecting %d; status 0x%x", exit_with, |
| 206 | exitcode, status); | 201 | exitcode, status); |
| 207 | if (mustpanic) | 202 | if (mustexit) |
| 208 | panic("\n"); | 203 | panic("\n"); |
| 209 | else | 204 | else |
| 210 | printk("\n"); | 205 | printk("\n"); |
| 211 | ret = -1; | 206 | ret = -1; |
| 212 | } | 207 | } |
| 213 | 208 | ||
| 214 | if(munmap(stack, PAGE_SIZE) < 0) | ||
| 215 | panic("check_ptrace : munmap failed, errno = %d", errno); | ||
| 216 | return ret; | 209 | return ret; |
| 217 | } | 210 | } |
| 218 | 211 | ||
| @@ -234,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param, | |||
| 234 | 227 | ||
| 235 | static void __init check_sysemu(void) | 228 | static void __init check_sysemu(void) |
| 236 | { | 229 | { |
| 237 | void *stack; | ||
| 238 | int pid, syscall, n, status, count=0; | 230 | int pid, syscall, n, status, count=0; |
| 239 | 231 | ||
| 240 | printk("Checking syscall emulation patch for ptrace..."); | 232 | printk("Checking syscall emulation patch for ptrace..."); |
| 241 | sysemu_supported = 0; | 233 | sysemu_supported = 0; |
| 242 | pid = start_ptraced_child(&stack); | 234 | pid = start_ptraced_child(); |
| 243 | 235 | ||
| 244 | if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) | 236 | if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) |
| 245 | goto fail; | 237 | goto fail; |
| @@ -257,7 +249,7 @@ static void __init check_sysemu(void) | |||
| 257 | panic("check_sysemu : failed to modify system " | 249 | panic("check_sysemu : failed to modify system " |
| 258 | "call return, errno = %d", errno); | 250 | "call return, errno = %d", errno); |
| 259 | 251 | ||
| 260 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 252 | if (stop_ptraced_child(pid, 0, 0) < 0) |
| 261 | goto fail_stopped; | 253 | goto fail_stopped; |
| 262 | 254 | ||
| 263 | sysemu_supported = 1; | 255 | sysemu_supported = 1; |
| @@ -265,7 +257,7 @@ static void __init check_sysemu(void) | |||
| 265 | set_using_sysemu(!force_sysemu_disabled); | 257 | set_using_sysemu(!force_sysemu_disabled); |
| 266 | 258 | ||
| 267 | printk("Checking advanced syscall emulation patch for ptrace..."); | 259 | printk("Checking advanced syscall emulation patch for ptrace..."); |
| 268 | pid = start_ptraced_child(&stack); | 260 | pid = start_ptraced_child(); |
| 269 | while(1){ | 261 | while(1){ |
| 270 | count++; | 262 | count++; |
| 271 | if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) | 263 | if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) |
| @@ -290,7 +282,7 @@ static void __init check_sysemu(void) | |||
| 290 | break; | 282 | break; |
| 291 | } | 283 | } |
| 292 | } | 284 | } |
| 293 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 285 | if (stop_ptraced_child(pid, 0, 0) < 0) |
| 294 | goto fail_stopped; | 286 | goto fail_stopped; |
| 295 | 287 | ||
| 296 | sysemu_supported = 2; | 288 | sysemu_supported = 2; |
| @@ -301,18 +293,17 @@ static void __init check_sysemu(void) | |||
| 301 | return; | 293 | return; |
| 302 | 294 | ||
| 303 | fail: | 295 | fail: |
| 304 | stop_ptraced_child(pid, stack, 1, 0); | 296 | stop_ptraced_child(pid, 1, 0); |
| 305 | fail_stopped: | 297 | fail_stopped: |
| 306 | printk("missing\n"); | 298 | printk("missing\n"); |
| 307 | } | 299 | } |
| 308 | 300 | ||
| 309 | void __init check_ptrace(void) | 301 | void __init check_ptrace(void) |
| 310 | { | 302 | { |
| 311 | void *stack; | ||
| 312 | int pid, syscall, n, status; | 303 | int pid, syscall, n, status; |
| 313 | 304 | ||
| 314 | printk("Checking that ptrace can change system call numbers..."); | 305 | printk("Checking that ptrace can change system call numbers..."); |
| 315 | pid = start_ptraced_child(&stack); | 306 | pid = start_ptraced_child(); |
| 316 | 307 | ||
| 317 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) | 308 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) |
| 318 | panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); | 309 | panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); |
| @@ -339,7 +330,7 @@ void __init check_ptrace(void) | |||
| 339 | break; | 330 | break; |
| 340 | } | 331 | } |
| 341 | } | 332 | } |
| 342 | stop_ptraced_child(pid, stack, 0, 1); | 333 | stop_ptraced_child(pid, 0, 1); |
| 343 | printk("OK\n"); | 334 | printk("OK\n"); |
| 344 | check_sysemu(); | 335 | check_sysemu(); |
| 345 | } | 336 | } |
| @@ -371,11 +362,10 @@ void forward_pending_sigio(int target) | |||
| 371 | static inline int check_skas3_ptrace_support(void) | 362 | static inline int check_skas3_ptrace_support(void) |
| 372 | { | 363 | { |
| 373 | struct ptrace_faultinfo fi; | 364 | struct ptrace_faultinfo fi; |
| 374 | void *stack; | ||
| 375 | int pid, n, ret = 1; | 365 | int pid, n, ret = 1; |
| 376 | 366 | ||
| 377 | printf("Checking for the skas3 patch in the host..."); | 367 | printf("Checking for the skas3 patch in the host..."); |
| 378 | pid = start_ptraced_child(&stack); | 368 | pid = start_ptraced_child(); |
| 379 | 369 | ||
| 380 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); | 370 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); |
| 381 | if (n < 0) { | 371 | if (n < 0) { |
| @@ -390,7 +380,7 @@ static inline int check_skas3_ptrace_support(void) | |||
| 390 | } | 380 | } |
| 391 | 381 | ||
| 392 | init_registers(pid); | 382 | init_registers(pid); |
| 393 | stop_ptraced_child(pid, stack, 1, 1); | 383 | stop_ptraced_child(pid, 1, 1); |
| 394 | 384 | ||
| 395 | return(ret); | 385 | return(ret); |
| 396 | } | 386 | } |
