master
c 519 lines 16.8 KB
Raw
1 /*
2 * qemu user cpu loop
3 *
4 * Copyright (c) 2003-2008 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
20 #include "qemu/osdep.h"
21 #include "qemu.h"
22 #include "user-internals.h"
23 #include "elf.h"
24 #include "user/cpu_loop.h"
25 #include "signal-common.h"
26 #include "semihosting/common-semi.h"
27 #include "exec/page-protection.h"
28 #include "exec/mmap-lock.h"
29 #include "user/page-protection.h"
30 #include "target/arm/syndrome.h"
31
32 #define get_user_code_u32(x, gaddr, env) \
33 ({ abi_long __r = get_user_u32((x), (gaddr)); \
34 if (!__r && bswap_code(arm_sctlr_b(env))) { \
35 (x) = bswap32(x); \
36 } \
37 __r; \
38 })
39
40 /*
41 * Note that if we need to do data accesses here, they should do a
42 * bswap if arm_cpu_bswap_data() returns true.
43 */
44
45 /*
46 * Similar to code in accel/tcg/user-exec.c, but outside the execution loop.
47 * Must be called with mmap_lock.
48 * We get the PC of the entry address - which is as good as anything,
49 * on a real kernel what you get depends on which mode it uses.
50 */
51 static void *atomic_mmu_lookup(CPUArchState *env, uint32_t addr, int size)
52 {
53 int need_flags = PAGE_READ | PAGE_WRITE_ORG | PAGE_VALID;
54 int page_flags;
55
56 /* Enforce guest required alignment. */
57 if (unlikely(addr & (size - 1))) {
58 force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, addr);
59 return NULL;
60 }
61
62 page_flags = page_get_flags(addr);
63 if (unlikely((page_flags & need_flags) != need_flags)) {
64 force_sig_fault(TARGET_SIGSEGV,
65 page_flags & PAGE_VALID ?
66 TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR, addr);
67 return NULL;
68 }
69
70 return g2h(env_cpu(env), addr);
71 }
72
73 /*
74 * See the Linux kernel's Documentation/arm/kernel_user_helpers.rst
75 * Input:
76 * r0 = oldval
77 * r1 = newval
78 * r2 = pointer to target value
79 *
80 * Output:
81 * r0 = 0 if *ptr was changed, non-0 if no exchange happened
82 * C set if *ptr was changed, clear if no exchange happened
83 */
84 static void arm_kernel_cmpxchg32_helper(CPUARMState *env)
85 {
86 uint32_t oldval, newval, val, addr, cpsr, *host_addr;
87
88 /* Swap if host != guest endianness, for the host cmpxchg below */
89 oldval = tswap32(env->regs[0]);
90 newval = tswap32(env->regs[1]);
91 addr = env->regs[2];
92
93 mmap_lock();
94 host_addr = atomic_mmu_lookup(env, addr, 4);
95 if (!host_addr) {
96 mmap_unlock();
97 return;
98 }
99
100 val = qatomic_cmpxchg__nocheck(host_addr, oldval, newval);
101 mmap_unlock();
102
103 cpsr = (val == oldval) * CPSR_C;
104 cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
105 env->regs[0] = cpsr ? 0 : -1;
106 }
107
108 /*
109 * See the Linux kernel's Documentation/arm/kernel_user_helpers.rst
110 * Input:
111 * r0 = pointer to oldval
112 * r1 = pointer to newval
113 * r2 = pointer to target value
114 *
115 * Output:
116 * r0 = 0 if *ptr was changed, non-0 if no exchange happened
117 * C set if *ptr was changed, clear if no exchange happened
118 *
119 * Note segv's in kernel helpers are a bit tricky, we can set the
120 * data address sensibly but the PC address is just the entry point.
121 */
122 static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
123 {
124 uint64_t oldval, newval, val;
125 uint32_t addr, cpsr;
126 uint64_t *host_addr;
127
128 addr = env->regs[0];
129 if (get_user_u64(oldval, addr)) {
130 goto segv;
131 }
132
133 addr = env->regs[1];
134 if (get_user_u64(newval, addr)) {
135 goto segv;
136 }
137
138 mmap_lock();
139 addr = env->regs[2];
140 host_addr = atomic_mmu_lookup(env, addr, 8);
141 if (!host_addr) {
142 mmap_unlock();
143 return;
144 }
145
146 /* Swap if host != guest endianness, for the host cmpxchg below */
147 oldval = tswap64(oldval);
148 newval = tswap64(newval);
149 val = qatomic_cmpxchg(host_addr, oldval, newval);
150 cpsr = (val == oldval) * CPSR_C;
151 mmap_unlock();
152
153 cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
154 env->regs[0] = cpsr ? 0 : -1;
155 return;
156
157 segv:
158 force_sig_fault(TARGET_SIGSEGV,
159 page_get_flags(addr) & PAGE_VALID ?
160 TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR, addr);
161 }
162
163 /* Handle a jump to the kernel code page. */
164 static int
165 do_kernel_trap(CPUARMState *env)
166 {
167 uint32_t addr;
168
169 switch (env->regs[15]) {
170 case 0xffff0fa0: /* __kernel_memory_barrier */
171 smp_mb();
172 break;
173 case 0xffff0fc0: /* __kernel_cmpxchg */
174 arm_kernel_cmpxchg32_helper(env);
175 break;
176 case 0xffff0fe0: /* __kernel_get_tls */
177 env->regs[0] = cpu_get_tls(env);
178 break;
179 case 0xffff0f60: /* __kernel_cmpxchg64 */
180 arm_kernel_cmpxchg64_helper(env);
181 break;
182
183 default:
184 return 1;
185 }
186 /* Jump back to the caller. */
187 addr = env->regs[14];
188 if (addr & 1) {
189 env->thumb = true;
190 addr &= ~1;
191 }
192 env->regs[15] = addr;
193
194 return 0;
195 }
196
197 static bool insn_is_linux_bkpt(uint32_t opcode, bool is_thumb)
198 {
199 /*
200 * Return true if this insn is one of the three magic UDF insns
201 * which the kernel treats as breakpoint insns.
202 */
203 if (!is_thumb) {
204 return (opcode & 0x0fffffff) == 0x07f001f0;
205 } else {
206 /*
207 * Note that we get the two halves of the 32-bit T32 insn
208 * in the opposite order to the value the kernel uses in
209 * its undef_hook struct.
210 */
211 return ((opcode & 0xffff) == 0xde01) || (opcode == 0xa000f7f0);
212 }
213 }
214
215 static bool emulate_arm_fpa11(CPUARMState *env, uint32_t opcode)
216 {
217 TaskState *ts = get_task_state(env_cpu(env));
218 int rc = EmulateAll(opcode, &ts->fpa);
219 int raise, enabled;
220
221 if (rc == 0) {
222 /* Illegal instruction */
223 return false;
224 }
225 if (rc > 0) {
226 /* Everything ok. */
227 env->regs[15] += 4;
228 return true;
229 }
230
231 /* FP exception */
232 rc = -rc;
233 raise = 0;
234
235 /* Translate softfloat flags to FPSR flags */
236 if (rc & float_flag_invalid) {
237 raise |= BIT_IOC;
238 }
239 if (rc & float_flag_divbyzero) {
240 raise |= BIT_DZC;
241 }
242 if (rc & float_flag_overflow) {
243 raise |= BIT_OFC;
244 }
245 if (rc & float_flag_underflow) {
246 raise |= BIT_UFC;
247 }
248 if (rc & float_flag_inexact) {
249 raise |= BIT_IXC;
250 }
251
252 /* Accumulate unenabled exceptions */
253 enabled = ts->fpa.fpsr >> 16;
254 ts->fpa.fpsr |= raise & ~enabled;
255
256 if (raise & enabled) {
257 /*
258 * The kernel's nwfpe emulator does not pass a real si_code.
259 * It merely uses send_sig(SIGFPE, current, 1), which results in
260 * __send_signal() filling out SI_KERNEL with pid and uid 0 (under
261 * the "SEND_SIG_PRIV" case). That's what our force_sig() does.
262 */
263 force_sig(TARGET_SIGFPE);
264 } else {
265 env->regs[15] += 4;
266 }
267 return true;
268 }
269
270 void cpu_loop(CPUARMState *env)
271 {
272 CPUState *cs = env_cpu(env);
273 int trapnr, si_signo, si_code;
274 unsigned int n, insn;
275 abi_ulong ret;
276
277 for(;;) {
278 cpu_exec_start(cs);
279 trapnr = cpu_exec(cs);
280 cpu_exec_end(cs);
281 qemu_process_cpu_events(cs);
282
283 switch(trapnr) {
284 case EXCP_UDEF:
285 case EXCP_NOCP:
286 case EXCP_INVSTATE:
287 {
288 uint32_t opcode;
289
290 /* we handle the FPU emulation here, as Linux */
291 /* we get the opcode */
292 /* FIXME - what to do if get_user() fails? */
293 get_user_code_u32(opcode, env->regs[15], env);
294
295 /*
296 * The Linux kernel treats some UDF patterns specially
297 * to use as breakpoints (instead of the architectural
298 * bkpt insn). These should trigger a SIGTRAP rather
299 * than SIGILL.
300 */
301 if (insn_is_linux_bkpt(opcode, env->thumb)) {
302 goto excp_debug;
303 }
304
305 if (!env->thumb && emulate_arm_fpa11(env, opcode)) {
306 break;
307 }
308
309 force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN,
310 env->regs[15]);
311 }
312 break;
313 case EXCP_SWI:
314 {
315 env->eabi = true;
316 /* system call */
317 if (env->thumb) {
318 /* Thumb is always EABI style with syscall number in r7 */
319 n = env->regs[7];
320 } else {
321 /*
322 * Equivalent of kernel CONFIG_OABI_COMPAT: read the
323 * Arm SVC insn to extract the immediate, which is the
324 * syscall number in OABI.
325 */
326 /* FIXME - what to do if get_user() fails? */
327 get_user_code_u32(insn, env->regs[15] - 4, env);
328 n = insn & 0xffffff;
329 if (n == 0) {
330 /* zero immediate: EABI, syscall number in r7 */
331 n = env->regs[7];
332 } else {
333 /*
334 * This XOR matches the kernel code: an immediate
335 * in the valid range (0x900000 .. 0x9fffff) is
336 * converted into the correct EABI-style syscall
337 * number; invalid immediates end up as values
338 * > 0xfffff and are handled below as out-of-range.
339 */
340 n ^= ARM_SYSCALL_BASE;
341 env->eabi = false;
342 }
343 }
344
345 if (n > ARM_NR_BASE) {
346 switch (n) {
347 case ARM_NR_cacheflush:
348 /* nop */
349 env->regs[0] = 0;
350 break;
351 case ARM_NR_set_tls:
352 cpu_set_tls(env, env->regs[0]);
353 env->regs[0] = 0;
354 break;
355 case ARM_NR_breakpoint:
356 env->regs[15] -= env->thumb ? 2 : 4;
357 goto excp_debug;
358 case ARM_NR_get_tls:
359 env->regs[0] = cpu_get_tls(env);
360 break;
361 default:
362 if (n < 0xf0800) {
363 /*
364 * Syscalls 0xf0000..0xf07ff (or 0x9f0000..
365 * 0x9f07ff in OABI numbering) are defined
366 * to return -ENOSYS rather than raising
367 * SIGILL. Note that we have already
368 * removed the 0x900000 prefix.
369 */
370 qemu_log_mask(LOG_UNIMP,
371 "qemu: Unsupported ARM syscall: 0x%x\n",
372 n);
373 env->regs[0] = -TARGET_ENOSYS;
374 } else {
375 /*
376 * Otherwise SIGILL. This includes any SWI with
377 * immediate not originally 0x9fxxxx, because
378 * of the earlier XOR.
379 * Like the real kernel, we report the addr of the
380 * SWI in the siginfo si_addr but leave the PC
381 * pointing at the insn after the SWI.
382 */
383 abi_ulong faultaddr = env->regs[15];
384 faultaddr -= env->thumb ? 2 : 4;
385 force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLTRP,
386 faultaddr);
387 }
388 break;
389 }
390 } else {
391 ret = do_syscall(env,
392 n,
393 env->regs[0],
394 env->regs[1],
395 env->regs[2],
396 env->regs[3],
397 env->regs[4],
398 env->regs[5],
399 0, 0);
400 if (ret == -QEMU_ERESTARTSYS) {
401 env->regs[15] -= env->thumb ? 2 : 4;
402 } else if (ret != -QEMU_ESIGRETURN && ret != -QEMU_ESETPC) {
403 env->regs[0] = ret;
404 }
405 }
406 }
407 break;
408 case EXCP_SEMIHOST:
409 do_common_semihosting(cs);
410 env->regs[15] += env->thumb ? 2 : 4;
411 break;
412 case EXCP_INTERRUPT:
413 /* just indicate that signals should be handled asap */
414 break;
415 case EXCP_PREFETCH_ABORT:
416 case EXCP_DATA_ABORT:
417 /* For user-only we don't set TTBCR_EAE, so look at the FSR. */
418 switch (env->exception.fsr & 0x1f) {
419 case 0x1: /* Alignment */
420 si_signo = TARGET_SIGBUS;
421 si_code = TARGET_BUS_ADRALN;
422 break;
423 case 0x3: /* Access flag fault, level 1 */
424 case 0x6: /* Access flag fault, level 2 */
425 case 0x9: /* Domain fault, level 1 */
426 case 0xb: /* Domain fault, level 2 */
427 case 0xd: /* Permission fault, level 1 */
428 case 0xf: /* Permission fault, level 2 */
429 si_signo = TARGET_SIGSEGV;
430 si_code = TARGET_SEGV_ACCERR;
431 break;
432 case 0x5: /* Translation fault, level 1 */
433 case 0x7: /* Translation fault, level 2 */
434 si_signo = TARGET_SIGSEGV;
435 si_code = TARGET_SEGV_MAPERR;
436 break;
437 default:
438 g_assert_not_reached();
439 }
440 force_sig_fault(si_signo, si_code, env->exception.vaddress);
441 break;
442 case EXCP_DEBUG:
443 case EXCP_BKPT:
444 excp_debug:
445 force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->regs[15]);
446 break;
447 case EXCP_KERNEL_TRAP:
448 if (do_kernel_trap(env))
449 goto error;
450 break;
451 case EXCP_YIELD:
452 /* nothing to do here for user-mode, just resume guest code */
453 break;
454 case EXCP_ATOMIC:
455 cpu_exec_step_atomic(cs);
456 break;
457 default:
458 error:
459 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
460 abort();
461 }
462 process_pending_signals(env);
463 }
464 }
465
466 void init_main_thread(CPUState *cs, struct image_info *info)
467 {
468 CPUARMState *env = cpu_env(cs);
469 abi_ptr stack = info->start_stack;
470 abi_ptr entry = info->entry;
471
472 cpsr_write(env, ARM_CPU_MODE_USR | (entry & 1 ? CPSR_T : 0),
473 CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
474
475 env->regs[15] = entry & 0xfffffffe;
476 env->regs[13] = stack;
477
478 /*
479 * Per the SVR4 ABI, r0 contains a pointer to a function to be
480 * registered with atexit. A value of 0 means we have no such handler.
481 */
482 env->regs[0] = 0;
483
484 /* For uClinux PIC binaries. */
485 /* XXX: Linux does this only on ARM with no MMU (do we care?) */
486 env->regs[10] = info->start_data;
487
488 /* Support ARM FDPIC. */
489 if (info_is_fdpic(info)) {
490 /*
491 * As described in the ABI document, r7 points to the loadmap info
492 * prepared by the kernel. If an interpreter is needed, r8 points
493 * to the interpreter loadmap and r9 points to the interpreter
494 * PT_DYNAMIC info. If no interpreter is needed, r8 is zero, and
495 * r9 points to the main program PT_DYNAMIC info.
496 */
497 env->regs[7] = info->loadmap_addr;
498 if (info->interpreter_loadmap_addr) {
499 /* Executable is dynamically loaded. */
500 env->regs[8] = info->interpreter_loadmap_addr;
501 env->regs[9] = info->interpreter_pt_dynamic_addr;
502 } else {
503 env->regs[8] = 0;
504 env->regs[9] = info->pt_dynamic_addr;
505 }
506 }
507
508 if (TARGET_BIG_ENDIAN) {
509 /* Enable BE8. */
510 if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
511 && (info->elf_flags & EF_ARM_BE8)) {
512 env->uncached_cpsr |= CPSR_E;
513 env->cp15.sctlr_el[1] |= SCTLR_E0E;
514 } else {
515 env->cp15.sctlr_el[1] |= SCTLR_B;
516 }
517 arm_rebuild_hflags(env);
518 }
519 }