]> git.proxmox.com Git - mirror_qemu.git/blob - linux-user/aarch64/signal.c
linux-user: Rename TARGET_QEMU_ESIGRETURN to QEMU_ESIGRETURN
[mirror_qemu.git] / linux-user / aarch64 / signal.c
1 /*
2 * Emulation of Linux signals
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "qemu/osdep.h"
20 #include "qemu.h"
21 #include "user-internals.h"
22 #include "signal-common.h"
23 #include "linux-user/trace.h"
24
25 struct target_sigcontext {
26 uint64_t fault_address;
27 /* AArch64 registers */
28 uint64_t regs[31];
29 uint64_t sp;
30 uint64_t pc;
31 uint64_t pstate;
32 /* 4K reserved for FP/SIMD state and future expansion */
33 char __reserved[4096] __attribute__((__aligned__(16)));
34 };
35
36 struct target_ucontext {
37 abi_ulong tuc_flags;
38 abi_ulong tuc_link;
39 target_stack_t tuc_stack;
40 target_sigset_t tuc_sigmask;
41 /* glibc uses a 1024-bit sigset_t */
42 char __unused[1024 / 8 - sizeof(target_sigset_t)];
43 /* last for future expansion */
44 struct target_sigcontext tuc_mcontext;
45 };
46
47 /*
48 * Header to be used at the beginning of structures extending the user
49 * context. Such structures must be placed after the rt_sigframe on the stack
50 * and be 16-byte aligned. The last structure must be a dummy one with the
51 * magic and size set to 0.
52 */
53 struct target_aarch64_ctx {
54 uint32_t magic;
55 uint32_t size;
56 };
57
58 #define TARGET_FPSIMD_MAGIC 0x46508001
59
60 struct target_fpsimd_context {
61 struct target_aarch64_ctx head;
62 uint32_t fpsr;
63 uint32_t fpcr;
64 uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
65 };
66
67 #define TARGET_EXTRA_MAGIC 0x45585401
68
69 struct target_extra_context {
70 struct target_aarch64_ctx head;
71 uint64_t datap; /* 16-byte aligned pointer to extra space cast to __u64 */
72 uint32_t size; /* size in bytes of the extra space */
73 uint32_t reserved[3];
74 };
75
76 #define TARGET_SVE_MAGIC 0x53564501
77
78 struct target_sve_context {
79 struct target_aarch64_ctx head;
80 uint16_t vl;
81 uint16_t reserved[3];
82 /* The actual SVE data immediately follows. It is laid out
83 * according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
84 * the original struct pointer.
85 */
86 };
87
88 #define TARGET_SVE_VQ_BYTES 16
89
90 #define TARGET_SVE_SIG_ZREG_SIZE(VQ) ((VQ) * TARGET_SVE_VQ_BYTES)
91 #define TARGET_SVE_SIG_PREG_SIZE(VQ) ((VQ) * (TARGET_SVE_VQ_BYTES / 8))
92
93 #define TARGET_SVE_SIG_REGS_OFFSET \
94 QEMU_ALIGN_UP(sizeof(struct target_sve_context), TARGET_SVE_VQ_BYTES)
95 #define TARGET_SVE_SIG_ZREG_OFFSET(VQ, N) \
96 (TARGET_SVE_SIG_REGS_OFFSET + TARGET_SVE_SIG_ZREG_SIZE(VQ) * (N))
97 #define TARGET_SVE_SIG_PREG_OFFSET(VQ, N) \
98 (TARGET_SVE_SIG_ZREG_OFFSET(VQ, 32) + TARGET_SVE_SIG_PREG_SIZE(VQ) * (N))
99 #define TARGET_SVE_SIG_FFR_OFFSET(VQ) \
100 (TARGET_SVE_SIG_PREG_OFFSET(VQ, 16))
101 #define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
102 (TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
103
104 struct target_rt_sigframe {
105 struct target_siginfo info;
106 struct target_ucontext uc;
107 };
108
109 struct target_rt_frame_record {
110 uint64_t fp;
111 uint64_t lr;
112 };
113
114 static void target_setup_general_frame(struct target_rt_sigframe *sf,
115 CPUARMState *env, target_sigset_t *set)
116 {
117 int i;
118
119 __put_user(0, &sf->uc.tuc_flags);
120 __put_user(0, &sf->uc.tuc_link);
121
122 target_save_altstack(&sf->uc.tuc_stack, env);
123
124 for (i = 0; i < 31; i++) {
125 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
126 }
127 __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
128 __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
129 __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
130
131 __put_user(env->exception.vaddress, &sf->uc.tuc_mcontext.fault_address);
132
133 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
134 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
135 }
136 }
137
138 static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
139 CPUARMState *env)
140 {
141 int i;
142
143 __put_user(TARGET_FPSIMD_MAGIC, &fpsimd->head.magic);
144 __put_user(sizeof(struct target_fpsimd_context), &fpsimd->head.size);
145 __put_user(vfp_get_fpsr(env), &fpsimd->fpsr);
146 __put_user(vfp_get_fpcr(env), &fpsimd->fpcr);
147
148 for (i = 0; i < 32; i++) {
149 uint64_t *q = aa64_vfp_qreg(env, i);
150 #ifdef TARGET_WORDS_BIGENDIAN
151 __put_user(q[0], &fpsimd->vregs[i * 2 + 1]);
152 __put_user(q[1], &fpsimd->vregs[i * 2]);
153 #else
154 __put_user(q[0], &fpsimd->vregs[i * 2]);
155 __put_user(q[1], &fpsimd->vregs[i * 2 + 1]);
156 #endif
157 }
158 }
159
160 static void target_setup_extra_record(struct target_extra_context *extra,
161 uint64_t datap, uint32_t extra_size)
162 {
163 __put_user(TARGET_EXTRA_MAGIC, &extra->head.magic);
164 __put_user(sizeof(struct target_extra_context), &extra->head.size);
165 __put_user(datap, &extra->datap);
166 __put_user(extra_size, &extra->size);
167 }
168
169 static void target_setup_end_record(struct target_aarch64_ctx *end)
170 {
171 __put_user(0, &end->magic);
172 __put_user(0, &end->size);
173 }
174
175 static void target_setup_sve_record(struct target_sve_context *sve,
176 CPUARMState *env, int vq, int size)
177 {
178 int i, j;
179
180 __put_user(TARGET_SVE_MAGIC, &sve->head.magic);
181 __put_user(size, &sve->head.size);
182 __put_user(vq * TARGET_SVE_VQ_BYTES, &sve->vl);
183
184 /* Note that SVE regs are stored as a byte stream, with each byte element
185 * at a subsequent address. This corresponds to a little-endian store
186 * of our 64-bit hunks.
187 */
188 for (i = 0; i < 32; ++i) {
189 uint64_t *z = (void *)sve + TARGET_SVE_SIG_ZREG_OFFSET(vq, i);
190 for (j = 0; j < vq * 2; ++j) {
191 __put_user_e(env->vfp.zregs[i].d[j], z + j, le);
192 }
193 }
194 for (i = 0; i <= 16; ++i) {
195 uint16_t *p = (void *)sve + TARGET_SVE_SIG_PREG_OFFSET(vq, i);
196 for (j = 0; j < vq; ++j) {
197 uint64_t r = env->vfp.pregs[i].p[j >> 2];
198 __put_user_e(r >> ((j & 3) * 16), p + j, le);
199 }
200 }
201 }
202
203 static void target_restore_general_frame(CPUARMState *env,
204 struct target_rt_sigframe *sf)
205 {
206 sigset_t set;
207 uint64_t pstate;
208 int i;
209
210 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
211 set_sigmask(&set);
212
213 for (i = 0; i < 31; i++) {
214 __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
215 }
216
217 __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
218 __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
219 __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
220 pstate_write(env, pstate);
221 }
222
223 static void target_restore_fpsimd_record(CPUARMState *env,
224 struct target_fpsimd_context *fpsimd)
225 {
226 uint32_t fpsr, fpcr;
227 int i;
228
229 __get_user(fpsr, &fpsimd->fpsr);
230 vfp_set_fpsr(env, fpsr);
231 __get_user(fpcr, &fpsimd->fpcr);
232 vfp_set_fpcr(env, fpcr);
233
234 for (i = 0; i < 32; i++) {
235 uint64_t *q = aa64_vfp_qreg(env, i);
236 #ifdef TARGET_WORDS_BIGENDIAN
237 __get_user(q[0], &fpsimd->vregs[i * 2 + 1]);
238 __get_user(q[1], &fpsimd->vregs[i * 2]);
239 #else
240 __get_user(q[0], &fpsimd->vregs[i * 2]);
241 __get_user(q[1], &fpsimd->vregs[i * 2 + 1]);
242 #endif
243 }
244 }
245
246 static void target_restore_sve_record(CPUARMState *env,
247 struct target_sve_context *sve, int vq)
248 {
249 int i, j;
250
251 /* Note that SVE regs are stored as a byte stream, with each byte element
252 * at a subsequent address. This corresponds to a little-endian load
253 * of our 64-bit hunks.
254 */
255 for (i = 0; i < 32; ++i) {
256 uint64_t *z = (void *)sve + TARGET_SVE_SIG_ZREG_OFFSET(vq, i);
257 for (j = 0; j < vq * 2; ++j) {
258 __get_user_e(env->vfp.zregs[i].d[j], z + j, le);
259 }
260 }
261 for (i = 0; i <= 16; ++i) {
262 uint16_t *p = (void *)sve + TARGET_SVE_SIG_PREG_OFFSET(vq, i);
263 for (j = 0; j < vq; ++j) {
264 uint16_t r;
265 __get_user_e(r, p + j, le);
266 if (j & 3) {
267 env->vfp.pregs[i].p[j >> 2] |= (uint64_t)r << ((j & 3) * 16);
268 } else {
269 env->vfp.pregs[i].p[j >> 2] = r;
270 }
271 }
272 }
273 }
274
275 static int target_restore_sigframe(CPUARMState *env,
276 struct target_rt_sigframe *sf)
277 {
278 struct target_aarch64_ctx *ctx, *extra = NULL;
279 struct target_fpsimd_context *fpsimd = NULL;
280 struct target_sve_context *sve = NULL;
281 uint64_t extra_datap = 0;
282 bool used_extra = false;
283 bool err = false;
284 int vq = 0, sve_size = 0;
285
286 target_restore_general_frame(env, sf);
287
288 ctx = (struct target_aarch64_ctx *)sf->uc.tuc_mcontext.__reserved;
289 while (ctx) {
290 uint32_t magic, size, extra_size;
291
292 __get_user(magic, &ctx->magic);
293 __get_user(size, &ctx->size);
294 switch (magic) {
295 case 0:
296 if (size != 0) {
297 err = true;
298 goto exit;
299 }
300 if (used_extra) {
301 ctx = NULL;
302 } else {
303 ctx = extra;
304 used_extra = true;
305 }
306 continue;
307
308 case TARGET_FPSIMD_MAGIC:
309 if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
310 err = true;
311 goto exit;
312 }
313 fpsimd = (struct target_fpsimd_context *)ctx;
314 break;
315
316 case TARGET_SVE_MAGIC:
317 if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
318 vq = (env->vfp.zcr_el[1] & 0xf) + 1;
319 sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
320 if (!sve && size == sve_size) {
321 sve = (struct target_sve_context *)ctx;
322 break;
323 }
324 }
325 err = true;
326 goto exit;
327
328 case TARGET_EXTRA_MAGIC:
329 if (extra || size != sizeof(struct target_extra_context)) {
330 err = true;
331 goto exit;
332 }
333 __get_user(extra_datap,
334 &((struct target_extra_context *)ctx)->datap);
335 __get_user(extra_size,
336 &((struct target_extra_context *)ctx)->size);
337 extra = lock_user(VERIFY_READ, extra_datap, extra_size, 0);
338 break;
339
340 default:
341 /* Unknown record -- we certainly didn't generate it.
342 * Did we in fact get out of sync?
343 */
344 err = true;
345 goto exit;
346 }
347 ctx = (void *)ctx + size;
348 }
349
350 /* Require FPSIMD always. */
351 if (fpsimd) {
352 target_restore_fpsimd_record(env, fpsimd);
353 } else {
354 err = true;
355 }
356
357 /* SVE data, if present, overwrites FPSIMD data. */
358 if (sve) {
359 target_restore_sve_record(env, sve, vq);
360 }
361
362 exit:
363 unlock_user(extra, extra_datap, 0);
364 return err;
365 }
366
367 static abi_ulong get_sigframe(struct target_sigaction *ka,
368 CPUARMState *env, int size)
369 {
370 abi_ulong sp;
371
372 sp = target_sigsp(get_sp_from_cpustate(env), ka);
373
374 sp = (sp - size) & ~15;
375
376 return sp;
377 }
378
379 typedef struct {
380 int total_size;
381 int extra_base;
382 int extra_size;
383 int std_end_ofs;
384 int extra_ofs;
385 int extra_end_ofs;
386 } target_sigframe_layout;
387
388 static int alloc_sigframe_space(int this_size, target_sigframe_layout *l)
389 {
390 /* Make sure there will always be space for the end marker. */
391 const int std_size = sizeof(struct target_rt_sigframe)
392 - sizeof(struct target_aarch64_ctx);
393 int this_loc = l->total_size;
394
395 if (l->extra_base) {
396 /* Once we have begun an extra space, all allocations go there. */
397 l->extra_size += this_size;
398 } else if (this_size + this_loc > std_size) {
399 /* This allocation does not fit in the standard space. */
400 /* Allocate the extra record. */
401 l->extra_ofs = this_loc;
402 l->total_size += sizeof(struct target_extra_context);
403
404 /* Allocate the standard end record. */
405 l->std_end_ofs = l->total_size;
406 l->total_size += sizeof(struct target_aarch64_ctx);
407
408 /* Allocate the requested record. */
409 l->extra_base = this_loc = l->total_size;
410 l->extra_size = this_size;
411 }
412 l->total_size += this_size;
413
414 return this_loc;
415 }
416
417 static void target_setup_frame(int usig, struct target_sigaction *ka,
418 target_siginfo_t *info, target_sigset_t *set,
419 CPUARMState *env)
420 {
421 target_sigframe_layout layout = {
422 /* Begin with the size pointing to the reserved space. */
423 .total_size = offsetof(struct target_rt_sigframe,
424 uc.tuc_mcontext.__reserved),
425 };
426 int fpsimd_ofs, fr_ofs, sve_ofs = 0, vq = 0, sve_size = 0;
427 struct target_rt_sigframe *frame;
428 struct target_rt_frame_record *fr;
429 abi_ulong frame_addr, return_addr;
430
431 /* FPSIMD record is always in the standard space. */
432 fpsimd_ofs = alloc_sigframe_space(sizeof(struct target_fpsimd_context),
433 &layout);
434
435 /* SVE state needs saving only if it exists. */
436 if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
437 vq = (env->vfp.zcr_el[1] & 0xf) + 1;
438 sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
439 sve_ofs = alloc_sigframe_space(sve_size, &layout);
440 }
441
442 if (layout.extra_ofs) {
443 /* Reserve space for the extra end marker. The standard end marker
444 * will have been allocated when we allocated the extra record.
445 */
446 layout.extra_end_ofs
447 = alloc_sigframe_space(sizeof(struct target_aarch64_ctx), &layout);
448 } else {
449 /* Reserve space for the standard end marker.
450 * Do not use alloc_sigframe_space because we cheat
451 * std_size therein to reserve space for this.
452 */
453 layout.std_end_ofs = layout.total_size;
454 layout.total_size += sizeof(struct target_aarch64_ctx);
455 }
456
457 /* We must always provide at least the standard 4K reserved space,
458 * even if we don't use all of it (this is part of the ABI)
459 */
460 layout.total_size = MAX(layout.total_size,
461 sizeof(struct target_rt_sigframe));
462
463 /*
464 * Reserve space for the standard frame unwind pair: fp, lr.
465 * Despite the name this is not a "real" record within the frame.
466 */
467 fr_ofs = layout.total_size;
468 layout.total_size += sizeof(struct target_rt_frame_record);
469
470 frame_addr = get_sigframe(ka, env, layout.total_size);
471 trace_user_setup_frame(env, frame_addr);
472 frame = lock_user(VERIFY_WRITE, frame_addr, layout.total_size, 0);
473 if (!frame) {
474 goto give_sigsegv;
475 }
476
477 target_setup_general_frame(frame, env, set);
478 target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
479 target_setup_end_record((void *)frame + layout.std_end_ofs);
480 if (layout.extra_ofs) {
481 target_setup_extra_record((void *)frame + layout.extra_ofs,
482 frame_addr + layout.extra_base,
483 layout.extra_size);
484 target_setup_end_record((void *)frame + layout.extra_end_ofs);
485 }
486 if (sve_ofs) {
487 target_setup_sve_record((void *)frame + sve_ofs, env, vq, sve_size);
488 }
489
490 /* Set up the stack frame for unwinding. */
491 fr = (void *)frame + fr_ofs;
492 __put_user(env->xregs[29], &fr->fp);
493 __put_user(env->xregs[30], &fr->lr);
494
495 if (ka->sa_flags & TARGET_SA_RESTORER) {
496 return_addr = ka->sa_restorer;
497 } else {
498 return_addr = default_rt_sigreturn;
499 }
500 env->xregs[0] = usig;
501 env->xregs[29] = frame_addr + fr_ofs;
502 env->xregs[30] = return_addr;
503 env->xregs[31] = frame_addr;
504 env->pc = ka->_sa_handler;
505
506 /* Invoke the signal handler as if by indirect call. */
507 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
508 env->btype = 2;
509 }
510
511 if (info) {
512 tswap_siginfo(&frame->info, info);
513 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
514 env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
515 }
516
517 unlock_user(frame, frame_addr, layout.total_size);
518 return;
519
520 give_sigsegv:
521 unlock_user(frame, frame_addr, layout.total_size);
522 force_sigsegv(usig);
523 }
524
525 void setup_rt_frame(int sig, struct target_sigaction *ka,
526 target_siginfo_t *info, target_sigset_t *set,
527 CPUARMState *env)
528 {
529 target_setup_frame(sig, ka, info, set, env);
530 }
531
532 void setup_frame(int sig, struct target_sigaction *ka,
533 target_sigset_t *set, CPUARMState *env)
534 {
535 target_setup_frame(sig, ka, 0, set, env);
536 }
537
538 long do_rt_sigreturn(CPUARMState *env)
539 {
540 struct target_rt_sigframe *frame = NULL;
541 abi_ulong frame_addr = env->xregs[31];
542
543 trace_user_do_rt_sigreturn(env, frame_addr);
544 if (frame_addr & 15) {
545 goto badframe;
546 }
547
548 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
549 goto badframe;
550 }
551
552 if (target_restore_sigframe(env, frame)) {
553 goto badframe;
554 }
555
556 target_restore_altstack(&frame->uc.tuc_stack, env);
557
558 unlock_user_struct(frame, frame_addr, 0);
559 return -QEMU_ESIGRETURN;
560
561 badframe:
562 unlock_user_struct(frame, frame_addr, 0);
563 force_sig(TARGET_SIGSEGV);
564 return -QEMU_ESIGRETURN;
565 }
566
567 long do_sigreturn(CPUARMState *env)
568 {
569 return do_rt_sigreturn(env);
570 }
571
572 void setup_sigtramp(abi_ulong sigtramp_page)
573 {
574 uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
575 assert(tramp != NULL);
576
577 /*
578 * mov x8,#__NR_rt_sigreturn; svc #0
579 * Since these are instructions they need to be put as little-endian
580 * regardless of target default or current CPU endianness.
581 */
582 __put_user_e(0xd2801168, &tramp[0], le);
583 __put_user_e(0xd4000001, &tramp[1], le);
584
585 default_rt_sigreturn = sigtramp_page;
586 unlock_user(tramp, sigtramp_page, 8);
587 }