diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 27 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 17 |
2 files changed, 39 insertions, 5 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, " |
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6ff3d98281ba..9ffc61ac8ed6 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
@@ -26,6 +26,21 @@ int set_interval(void) | |||
26 | return 0; | 26 | return 0; |
27 | } | 27 | } |
28 | 28 | ||
29 | int timer_one_shot(int ticks) | ||
30 | { | ||
31 | unsigned long usec = ticks * 1000000 / UM_HZ; | ||
32 | unsigned long sec = usec / 1000000; | ||
33 | struct itimerval interval; | ||
34 | |||
35 | usec %= 1000000; | ||
36 | interval = ((struct itimerval) { { 0, 0 }, { sec, usec } }); | ||
37 | |||
38 | if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1) | ||
39 | return -errno; | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
29 | void disable_timer(void) | 44 | void disable_timer(void) |
30 | { | 45 | { |
31 | struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); | 46 | struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); |
@@ -74,7 +89,7 @@ unsigned long long os_nsecs(void) | |||
74 | struct timeval tv; | 89 | struct timeval tv; |
75 | 90 | ||
76 | gettimeofday(&tv, NULL); | 91 | gettimeofday(&tv, NULL); |
77 | return (unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000; | 92 | return timeval_to_ns(&tv); |
78 | } | 93 | } |
79 | 94 | ||
80 | void idle_sleep(int secs) | 95 | void idle_sleep(int secs) |