diff options
Diffstat (limited to 'arch/um/os-Linux/skas/process.c')
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 0036164bb0fb..3e64814e888e 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -287,10 +287,18 @@ int start_userspace(unsigned long stub_stack) | |||
287 | 287 | ||
288 | void userspace(struct uml_pt_regs *regs) | 288 | void userspace(struct uml_pt_regs *regs) |
289 | { | 289 | { |
290 | struct itimerval timer; | ||
291 | unsigned long long nsecs, now; | ||
290 | int err, status, op, pid = userspace_pid[0]; | 292 | int err, status, op, pid = userspace_pid[0]; |
291 | /* To prevent races if using_sysemu changes under us.*/ | 293 | /* To prevent races if using_sysemu changes under us.*/ |
292 | int local_using_sysemu; | 294 | int local_using_sysemu; |
293 | 295 | ||
296 | if (getitimer(ITIMER_VIRTUAL, &timer)) | ||
297 | printk("Failed to get itimer, errno = %d\n", errno); | ||
298 | nsecs = timer.it_value.tv_sec * BILLION + | ||
299 | timer.it_value.tv_usec * 1000; | ||
300 | nsecs += os_nsecs(); | ||
301 | |||
294 | while (1) { | 302 | while (1) { |
295 | restore_registers(pid, regs); | 303 | restore_registers(pid, regs); |
296 | 304 | ||
@@ -333,8 +341,18 @@ void userspace(struct uml_pt_regs *regs) | |||
333 | case SIGTRAP: | 341 | case SIGTRAP: |
334 | relay_signal(SIGTRAP, regs); | 342 | relay_signal(SIGTRAP, regs); |
335 | break; | 343 | break; |
336 | case SIGIO: | ||
337 | case SIGVTALRM: | 344 | case SIGVTALRM: |
345 | now = os_nsecs(); | ||
346 | if(now < nsecs) | ||
347 | break; | ||
348 | block_signals(); | ||
349 | (*sig_info[sig])(sig, regs); | ||
350 | unblock_signals(); | ||
351 | nsecs = timer.it_value.tv_sec * BILLION + | ||
352 | timer.it_value.tv_usec * 1000; | ||
353 | nsecs += os_nsecs(); | ||
354 | break; | ||
355 | case SIGIO: | ||
338 | case SIGILL: | 356 | case SIGILL: |
339 | case SIGBUS: | 357 | case SIGBUS: |
340 | case SIGFPE: | 358 | case SIGFPE: |
@@ -378,6 +396,7 @@ __initcall(init_thread_regs); | |||
378 | 396 | ||
379 | int copy_context_skas0(unsigned long new_stack, int pid) | 397 | int copy_context_skas0(unsigned long new_stack, int pid) |
380 | { | 398 | { |
399 | struct timeval tv = { .tv_sec = 0, .tv_usec = 1000000 / UM_HZ }; | ||
381 | int err; | 400 | int err; |
382 | unsigned long current_stack = current_stub_stack(); | 401 | unsigned long current_stack = current_stub_stack(); |
383 | struct stub_data *data = (struct stub_data *) current_stack; | 402 | struct stub_data *data = (struct stub_data *) current_stack; |
@@ -392,9 +411,9 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
392 | *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), | 411 | *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), |
393 | .fd = new_fd, | 412 | .fd = new_fd, |
394 | .timer = ((struct itimerval) | 413 | .timer = ((struct itimerval) |
395 | { { 0, 1000000 / UM_HZ }, | 414 | { .it_value = tv, |
396 | { 0, 1000000 / UM_HZ }}) | 415 | .it_interval = tv }) }); |
397 | }); | 416 | |
398 | err = ptrace_setregs(pid, thread_regs); | 417 | err = ptrace_setregs(pid, thread_regs); |
399 | if (err < 0) | 418 | if (err < 0) |
400 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " | 419 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " |