hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/um/os-Linux/signal.c
....@@ -1,15 +1,16 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
34 * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
45 * Copyright (C) 2004 PathScale, Inc
56 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
6
- * Licensed under the GPL
77 */
88
99 #include <stdlib.h>
1010 #include <stdarg.h>
1111 #include <errno.h>
1212 #include <signal.h>
13
+#include <string.h>
1314 #include <strings.h>
1415 #include <as-layout.h>
1516 #include <kern_util.h>
....@@ -26,34 +27,27 @@
2627 [SIGBUS] = bus_handler,
2728 [SIGSEGV] = segv_handler,
2829 [SIGIO] = sigio_handler,
29
- [SIGALRM] = timer_handler
3030 };
3131
3232 static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
3333 {
34
- struct uml_pt_regs *r;
34
+ struct uml_pt_regs r;
3535 int save_errno = errno;
3636
37
- r = uml_kmalloc(sizeof(struct uml_pt_regs), UM_GFP_ATOMIC);
38
- if (!r)
39
- panic("out of memory");
40
-
41
- r->is_user = 0;
37
+ r.is_user = 0;
4238 if (sig == SIGSEGV) {
4339 /* For segfaults, we want the data from the sigcontext. */
44
- get_regs_from_mc(r, mc);
45
- GET_FAULTINFO_FROM_MC(r->faultinfo, mc);
40
+ get_regs_from_mc(&r, mc);
41
+ GET_FAULTINFO_FROM_MC(r.faultinfo, mc);
4642 }
4743
4844 /* enable signals if sig isn't IRQ signal */
49
- if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGALRM))
50
- unblock_signals();
45
+ if ((sig != SIGIO) && (sig != SIGWINCH))
46
+ unblock_signals_trace();
5147
52
- (*sig_info[sig])(sig, si, r);
48
+ (*sig_info[sig])(sig, si, &r);
5349
5450 errno = save_errno;
55
-
56
- free(r);
5751 }
5852
5953 /*
....@@ -82,26 +76,22 @@
8276 return;
8377 }
8478
85
- block_signals();
79
+ block_signals_trace();
8680
8781 sig_handler_common(sig, si, mc);
8882
89
- set_signals(enabled);
83
+ set_signals_trace(enabled);
9084 }
9185
9286 static void timer_real_alarm_handler(mcontext_t *mc)
9387 {
94
- struct uml_pt_regs *regs;
95
-
96
- regs = uml_kmalloc(sizeof(struct uml_pt_regs), UM_GFP_ATOMIC);
97
- if (!regs)
98
- panic("out of memory");
88
+ struct uml_pt_regs regs;
9989
10090 if (mc != NULL)
101
- get_regs_from_mc(regs, mc);
102
- timer_handler(SIGALRM, NULL, regs);
103
-
104
- free(regs);
91
+ get_regs_from_mc(&regs, mc);
92
+ else
93
+ memset(&regs, 0, sizeof(regs));
94
+ timer_handler(SIGALRM, NULL, &regs);
10595 }
10696
10797 void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
....@@ -114,7 +104,7 @@
114104 return;
115105 }
116106
117
- block_signals();
107
+ block_signals_trace();
118108
119109 signals_active |= SIGALRM_MASK;
120110
....@@ -122,7 +112,7 @@
122112
123113 signals_active &= ~SIGALRM_MASK;
124114
125
- set_signals(enabled);
115
+ set_signals_trace(enabled);
126116 }
127117
128118 void deliver_alarm(void) {
....@@ -146,6 +136,16 @@
146136 panic("enabling signal stack failed, errno = %d\n", errno);
147137 }
148138
139
+static void sigusr1_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
140
+{
141
+ uml_pm_wake();
142
+}
143
+
144
+void register_pm_wake_signal(void)
145
+{
146
+ set_handler(SIGUSR1);
147
+}
148
+
149149 static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = {
150150 [SIGSEGV] = sig_handler,
151151 [SIGBUS] = sig_handler,
....@@ -155,7 +155,9 @@
155155
156156 [SIGIO] = sig_handler,
157157 [SIGWINCH] = sig_handler,
158
- [SIGALRM] = timer_alarm_handler
158
+ [SIGALRM] = timer_alarm_handler,
159
+
160
+ [SIGUSR1] = sigusr1_handler,
159161 };
160162
161163 static void hard_handler(int sig, siginfo_t *si, void *p)
....@@ -263,6 +265,8 @@
263265 if (signals_enabled == 1)
264266 return;
265267
268
+ signals_enabled = 1;
269
+
266270 /*
267271 * We loop because the IRQ handler returns with interrupts off. So,
268272 * interrupts may have arrived and we need to re-enable them and
....@@ -272,12 +276,9 @@
272276 /*
273277 * Save and reset save_pending after enabling signals. This
274278 * way, signals_pending won't be changed while we're reading it.
275
- */
276
- signals_enabled = 1;
277
-
278
- /*
279
+ *
279280 * Setting signals_enabled and reading signals_pending must
280
- * happen in this order.
281
+ * happen in this order, so have the barrier here.
281282 */
282283 barrier();
283284
....@@ -290,10 +291,13 @@
290291 /*
291292 * We have pending interrupts, so disable signals, as the
292293 * handlers expect them off when they are called. They will
293
- * be enabled again above.
294
+ * be enabled again above. We need to trace this, as we're
295
+ * expected to be enabling interrupts already, but any more
296
+ * tracing that happens inside the handlers we call for the
297
+ * pending signals will mess up the tracing state.
294298 */
295
-
296299 signals_enabled = 0;
300
+ um_trace_signals_off();
297301
298302 /*
299303 * Deal with SIGIO first because the alarm handler might
....@@ -316,6 +320,9 @@
316320 if (!(signals_pending & SIGIO_MASK) && (signals_active & SIGALRM_MASK))
317321 return;
318322
323
+ /* Re-enable signals and trace that we're doing so. */
324
+ um_trace_signals_on();
325
+ signals_enabled = 1;
319326 }
320327 }
321328
....@@ -338,6 +345,21 @@
338345 return ret;
339346 }
340347
348
+int set_signals_trace(int enable)
349
+{
350
+ int ret;
351
+ if (signals_enabled == enable)
352
+ return enable;
353
+
354
+ ret = signals_enabled;
355
+ if (enable)
356
+ unblock_signals_trace();
357
+ else
358
+ block_signals_trace();
359
+
360
+ return ret;
361
+}
362
+
341363 int os_is_signal_stack(void)
342364 {
343365 stack_t ss;