diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/signal.c | 9 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 27 |
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(®s, sc); | 63 | copy_sc(®s, sc); |
67 | regs.is_user = 0; | 64 | regs.is_user = 0; |
68 | unblock_signals(); | 65 | unblock_signals(); |
69 | timer_handler(sig, ®s); | 66 | timer_handler(sig, ®s); |
70 | |||
71 | if (sig == SIGALRM) | ||
72 | switch_timers(1); | ||
73 | } | 67 | } |
74 | 68 | ||
75 | void alarm_handler(int sig, struct sigcontext *sc) | 69 | void alarm_handler(int sig, struct sigcontext *sc) |
@@ -116,6 +110,7 @@ void (*handlers[_NSIG])(int sig, struct sigcontext *sc); | |||
116 | void handle_signal(int sig, struct sigcontext *sc) | 110 | void 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 | ||
157 | extern void hard_handler(int sig); | 154 | extern 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 | ||
15 | static int is_real_timer = 0; | ||
16 | |||
15 | int set_interval(int is_virtual) | 17 | int 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 | ||
42 | void switch_timers(int to_real) | 44 | int 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 | ||
64 | unsigned long long os_nsecs(void) | 77 | unsigned long long os_nsecs(void) |