aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r--arch/um/os-Linux/skas/process.c27
-rw-r--r--arch/um/os-Linux/time.c17
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
288void userspace(struct uml_pt_regs *regs) 288void 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
379int copy_context_skas0(unsigned long new_stack, int pid) 397int 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
29int 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
29void disable_timer(void) 44void 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
80void idle_sleep(int secs) 95void idle_sleep(int secs)