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/signal.c9
-rw-r--r--arch/um/os-Linux/time.c27
2 files changed, 23 insertions, 13 deletions
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 49c113b576b7..1c5267ec13b0 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -59,17 +59,11 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
59{ 59{
60 struct uml_pt_regs regs; 60 struct uml_pt_regs regs;
61 61
62 if (sig == SIGALRM)
63 switch_timers(0);
64
65 if (sc != NULL) 62 if (sc != NULL)
66 copy_sc(&regs, sc); 63 copy_sc(&regs, sc);
67 regs.is_user = 0; 64 regs.is_user = 0;
68 unblock_signals(); 65 unblock_signals();
69 timer_handler(sig, &regs); 66 timer_handler(sig, &regs);
70
71 if (sig == SIGALRM)
72 switch_timers(1);
73} 67}
74 68
75void alarm_handler(int sig, struct sigcontext *sc) 69void alarm_handler(int sig, struct sigcontext *sc)
@@ -116,6 +110,7 @@ void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
116void handle_signal(int sig, struct sigcontext *sc) 110void handle_signal(int sig, struct sigcontext *sc)
117{ 111{
118 unsigned long pending = 1UL << sig; 112 unsigned long pending = 1UL << sig;
113 int timer = switch_timers(0);
119 114
120 do { 115 do {
121 int nested, bail; 116 int nested, bail;
@@ -152,6 +147,8 @@ void handle_signal(int sig, struct sigcontext *sc)
152 if (!nested) 147 if (!nested)
153 pending = from_irq_stack(nested); 148 pending = from_irq_stack(nested);
154 } while (pending); 149 } while (pending);
150
151 switch_timers(timer);
155} 152}
156 153
157extern void hard_handler(int sig); 154extern void hard_handler(int sig);
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 5939653f99ea..a16a0f484edc 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -12,6 +12,8 @@
12#include "os.h" 12#include "os.h"
13#include "user.h" 13#include "user.h"
14 14
15static int is_real_timer = 0;
16
15int set_interval(int is_virtual) 17int set_interval(int is_virtual)
16{ 18{
17 int usec = 1000000/UM_HZ; 19 int usec = 1000000/UM_HZ;
@@ -39,12 +41,14 @@ void disable_timer(void)
39 signal(SIGVTALRM, SIG_IGN); 41 signal(SIGVTALRM, SIG_IGN);
40} 42}
41 43
42void switch_timers(int to_real) 44int switch_timers(int to_real)
43{ 45{
44 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); 46 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
45 struct itimerval enable = ((struct itimerval) { { 0, 1000000/UM_HZ }, 47 struct itimerval enable;
46 { 0, 1000000/UM_HZ }}); 48 int old, new, old_type = is_real_timer;
47 int old, new; 49
50 if(to_real == old_type)
51 return to_real;
48 52
49 if (to_real) { 53 if (to_real) {
50 old = ITIMER_VIRTUAL; 54 old = ITIMER_VIRTUAL;
@@ -55,10 +59,19 @@ void switch_timers(int to_real)
55 new = ITIMER_VIRTUAL; 59 new = ITIMER_VIRTUAL;
56 } 60 }
57 61
58 if ((setitimer(old, &disable, NULL) < 0) || 62 if (setitimer(old, &disable, &enable) < 0)
59 (setitimer(new, &enable, NULL))) 63 printk(UM_KERN_ERR "switch_timers - setitimer disable failed, "
60 printk(UM_KERN_ERR "switch_timers - setitimer failed, " 64 "errno = %d\n", errno);
65
66 if((enable.it_value.tv_sec == 0) && (enable.it_value.tv_usec == 0))
67 enable.it_value = enable.it_interval;
68
69 if (setitimer(new, &enable, NULL))
70 printk(UM_KERN_ERR "switch_timers - setitimer enable failed, "
61 "errno = %d\n", errno); 71 "errno = %d\n", errno);
72
73 is_real_timer = to_real;
74 return old_type;
62} 75}
63 76
64unsigned long long os_nsecs(void) 77unsigned long long os_nsecs(void)