1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include "config.h"
20#include "exec.h"
21#include "disas.h"
22#include "tcg.h"
23#include "kvm.h"
24#include "qemu-barrier.h"
25
26#if !defined(CONFIG_SOFTMMU)
27#undef EAX
28#undef ECX
29#undef EDX
30#undef EBX
31#undef ESP
32#undef EBP
33#undef ESI
34#undef EDI
35#undef EIP
36#include <signal.h>
37#ifdef __linux__
38#include <sys/ucontext.h>
39#endif
40#endif
41
42#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
43
44#undef env
45#define env cpu_single_env
46#endif
47
48int tb_invalidated_flag;
49
50
51
52
53int qemu_cpu_has_work(CPUState *env)
54{
55 return cpu_has_work(env);
56}
57
58void cpu_loop_exit(void)
59{
60 env->current_tb = NULL;
61 longjmp(env->jmp_env, 1);
62}
63
64
65
66
67void cpu_resume_from_signal(CPUState *env1, void *puc)
68{
69#if !defined(CONFIG_SOFTMMU)
70#ifdef __linux__
71 struct ucontext *uc = puc;
72#elif defined(__OpenBSD__)
73 struct sigcontext *uc = puc;
74#endif
75#endif
76
77 env = env1;
78
79
80
81#if !defined(CONFIG_SOFTMMU)
82 if (puc) {
83
84#ifdef __linux__
85#ifdef __ia64
86 sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
87#else
88 sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
89#endif
90#elif defined(__OpenBSD__)
91 sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
92#endif
93 }
94#endif
95 env->exception_index = -1;
96 longjmp(env->jmp_env, 1);
97}
98
99
100
101static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
102{
103 unsigned long next_tb;
104 TranslationBlock *tb;
105
106
107
108 if (max_cycles > CF_COUNT_MASK)
109 max_cycles = CF_COUNT_MASK;
110
111 tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
112 max_cycles);
113 env->current_tb = tb;
114
115 next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
116 env->current_tb = NULL;
117
118 if ((next_tb & 3) == 2) {
119
120
121 cpu_pc_from_tb(env, tb);
122 }
123 tb_phys_invalidate(tb, -1);
124 tb_free(tb);
125}
126
127static TranslationBlock *tb_find_slow(target_ulong pc,
128 target_ulong cs_base,
129 uint64_t flags)
130{
131 TranslationBlock *tb, **ptb1;
132 unsigned int h;
133 tb_page_addr_t phys_pc, phys_page1, phys_page2;
134 target_ulong virt_page2;
135
136 tb_invalidated_flag = 0;
137
138
139 phys_pc = get_page_addr_code(env, pc);
140 phys_page1 = phys_pc & TARGET_PAGE_MASK;
141 phys_page2 = -1;
142 h = tb_phys_hash_func(phys_pc);
143 ptb1 = &tb_phys_hash[h];
144 for(;;) {
145 tb = *ptb1;
146 if (!tb)
147 goto not_found;
148 if (tb->pc == pc &&
149 tb->page_addr[0] == phys_page1 &&
150 tb->cs_base == cs_base &&
151 tb->flags == flags) {
152
153 if (tb->page_addr[1] != -1) {
154 virt_page2 = (pc & TARGET_PAGE_MASK) +
155 TARGET_PAGE_SIZE;
156 phys_page2 = get_page_addr_code(env, virt_page2);
157 if (tb->page_addr[1] == phys_page2)
158 goto found;
159 } else {
160 goto found;
161 }
162 }
163 ptb1 = &tb->phys_hash_next;
164 }
165 not_found:
166
167 tb = tb_gen_code(env, pc, cs_base, flags, 0);
168
169 found:
170
171 if (likely(*ptb1)) {
172 *ptb1 = tb->phys_hash_next;
173 tb->phys_hash_next = tb_phys_hash[h];
174 tb_phys_hash[h] = tb;
175 }
176
177 env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
178 return tb;
179}
180
181static inline TranslationBlock *tb_find_fast(void)
182{
183 TranslationBlock *tb;
184 target_ulong cs_base, pc;
185 int flags;
186
187
188
189
190 cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
191 tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
192 if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
193 tb->flags != flags)) {
194 tb = tb_find_slow(pc, cs_base, flags);
195 }
196 return tb;
197}
198
199static CPUDebugExcpHandler *debug_excp_handler;
200
201CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
202{
203 CPUDebugExcpHandler *old_handler = debug_excp_handler;
204
205 debug_excp_handler = handler;
206 return old_handler;
207}
208
209static void cpu_handle_debug_exception(CPUState *env)
210{
211 CPUWatchpoint *wp;
212
213 if (!env->watchpoint_hit)
214 QTAILQ_FOREACH(wp, &env->watchpoints, entry)
215 wp->flags &= ~BP_WATCHPOINT_HIT;
216
217 if (debug_excp_handler)
218 debug_excp_handler(env);
219}
220
221
222
223volatile sig_atomic_t exit_request;
224
225int cpu_exec(CPUState *env1)
226{
227 volatile host_reg_t saved_env_reg;
228 int ret, interrupt_request;
229 TranslationBlock *tb;
230 uint8_t *tc_ptr;
231 unsigned long next_tb;
232
233 if (cpu_halted(env1) == EXCP_HALTED)
234 return EXCP_HALTED;
235
236 cpu_single_env = env1;
237
238
239
240
241 QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env));
242 saved_env_reg = (host_reg_t) env;
243 barrier();
244 env = env1;
245
246 if (unlikely(exit_request)) {
247 env->exit_request = 1;
248 }
249
250#if defined(TARGET_I386)
251 if (!kvm_enabled()) {
252
253 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
254 DF = 1 - (2 * ((env->eflags >> 10) & 1));
255 CC_OP = CC_OP_EFLAGS;
256 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
257 }
258#elif defined(TARGET_SPARC)
259#elif defined(TARGET_M68K)
260 env->cc_op = CC_OP_FLAGS;
261 env->cc_dest = env->sr & 0xf;
262 env->cc_x = (env->sr >> 4) & 1;
263#elif defined(TARGET_ALPHA)
264#elif defined(TARGET_ARM)
265#elif defined(TARGET_PPC)
266#elif defined(TARGET_MICROBLAZE)
267#elif defined(TARGET_MIPS)
268#elif defined(TARGET_SH4)
269#elif defined(TARGET_CRIS)
270#elif defined(TARGET_S390X)
271
272#else
273#error unsupported target CPU
274#endif
275 env->exception_index = -1;
276
277
278 for(;;) {
279 if (setjmp(env->jmp_env) == 0) {
280#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
281#undef env
282 env = cpu_single_env;
283#define env cpu_single_env
284#endif
285
286 if (env->exception_index >= 0) {
287 if (env->exception_index >= EXCP_INTERRUPT) {
288
289 ret = env->exception_index;
290 if (ret == EXCP_DEBUG)
291 cpu_handle_debug_exception(env);
292 break;
293 } else {
294#if defined(CONFIG_USER_ONLY)
295
296
297
298#if defined(TARGET_I386)
299 do_interrupt_user(env->exception_index,
300 env->exception_is_int,
301 env->error_code,
302 env->exception_next_eip);
303
304 env->old_exception = -1;
305#endif
306 ret = env->exception_index;
307 break;
308#else
309#if defined(TARGET_I386)
310
311
312
313 do_interrupt(env->exception_index,
314 env->exception_is_int,
315 env->error_code,
316 env->exception_next_eip, 0);
317
318 env->old_exception = -1;
319#elif defined(TARGET_PPC)
320 do_interrupt(env);
321#elif defined(TARGET_MICROBLAZE)
322 do_interrupt(env);
323#elif defined(TARGET_MIPS)
324 do_interrupt(env);
325#elif defined(TARGET_SPARC)
326 do_interrupt(env);
327#elif defined(TARGET_ARM)
328 do_interrupt(env);
329#elif defined(TARGET_SH4)
330 do_interrupt(env);
331#elif defined(TARGET_ALPHA)
332 do_interrupt(env);
333#elif defined(TARGET_CRIS)
334 do_interrupt(env);
335#elif defined(TARGET_M68K)
336 do_interrupt(0);
337#endif
338 env->exception_index = -1;
339#endif
340 }
341 }
342
343 if (kvm_enabled()) {
344 kvm_cpu_exec(env);
345 longjmp(env->jmp_env, 1);
346 }
347
348 next_tb = 0;
349 for(;;) {
350 interrupt_request = env->interrupt_request;
351 if (unlikely(interrupt_request)) {
352 if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
353
354 interrupt_request &= ~(CPU_INTERRUPT_HARD |
355 CPU_INTERRUPT_FIQ |
356 CPU_INTERRUPT_SMI |
357 CPU_INTERRUPT_NMI);
358 }
359 if (interrupt_request & CPU_INTERRUPT_DEBUG) {
360 env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
361 env->exception_index = EXCP_DEBUG;
362 cpu_loop_exit();
363 }
364#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
365 defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
366 defined(TARGET_MICROBLAZE)
367 if (interrupt_request & CPU_INTERRUPT_HALT) {
368 env->interrupt_request &= ~CPU_INTERRUPT_HALT;
369 env->halted = 1;
370 env->exception_index = EXCP_HLT;
371 cpu_loop_exit();
372 }
373#endif
374#if defined(TARGET_I386)
375 if (interrupt_request & CPU_INTERRUPT_INIT) {
376 svm_check_intercept(SVM_EXIT_INIT);
377 do_cpu_init(env);
378 env->exception_index = EXCP_HALTED;
379 cpu_loop_exit();
380 } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
381 do_cpu_sipi(env);
382 } else if (env->hflags2 & HF2_GIF_MASK) {
383 if ((interrupt_request & CPU_INTERRUPT_SMI) &&
384 !(env->hflags & HF_SMM_MASK)) {
385 svm_check_intercept(SVM_EXIT_SMI);
386 env->interrupt_request &= ~CPU_INTERRUPT_SMI;
387 do_smm_enter();
388 next_tb = 0;
389 } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
390 !(env->hflags2 & HF2_NMI_MASK)) {
391 env->interrupt_request &= ~CPU_INTERRUPT_NMI;
392 env->hflags2 |= HF2_NMI_MASK;
393 do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
394 next_tb = 0;
395 } else if (interrupt_request & CPU_INTERRUPT_MCE) {
396 env->interrupt_request &= ~CPU_INTERRUPT_MCE;
397 do_interrupt(EXCP12_MCHK, 0, 0, 0, 0);
398 next_tb = 0;
399 } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
400 (((env->hflags2 & HF2_VINTR_MASK) &&
401 (env->hflags2 & HF2_HIF_MASK)) ||
402 (!(env->hflags2 & HF2_VINTR_MASK) &&
403 (env->eflags & IF_MASK &&
404 !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
405 int intno;
406 svm_check_intercept(SVM_EXIT_INTR);
407 env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
408 intno = cpu_get_pic_interrupt(env);
409 qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
410#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
411#undef env
412 env = cpu_single_env;
413#define env cpu_single_env
414#endif
415 do_interrupt(intno, 0, 0, 0, 1);
416
417
418 next_tb = 0;
419#if !defined(CONFIG_USER_ONLY)
420 } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
421 (env->eflags & IF_MASK) &&
422 !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
423 int intno;
424
425 svm_check_intercept(SVM_EXIT_VINTR);
426 intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
427 qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
428 do_interrupt(intno, 0, 0, 0, 1);
429 env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
430 next_tb = 0;
431#endif
432 }
433 }
434#elif defined(TARGET_PPC)
435#if 0
436 if ((interrupt_request & CPU_INTERRUPT_RESET)) {
437 cpu_reset(env);
438 }
439#endif
440 if (interrupt_request & CPU_INTERRUPT_HARD) {
441 ppc_hw_interrupt(env);
442 if (env->pending_interrupts == 0)
443 env->interrupt_request &= ~CPU_INTERRUPT_HARD;
444 next_tb = 0;
445 }
446#elif defined(TARGET_MICROBLAZE)
447 if ((interrupt_request & CPU_INTERRUPT_HARD)
448 && (env->sregs[SR_MSR] & MSR_IE)
449 && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
450 && !(env->iflags & (D_FLAG | IMM_FLAG))) {
451 env->exception_index = EXCP_IRQ;
452 do_interrupt(env);
453 next_tb = 0;
454 }
455#elif defined(TARGET_MIPS)
456 if ((interrupt_request & CPU_INTERRUPT_HARD) &&
457 cpu_mips_hw_interrupts_pending(env)) {
458
459 env->exception_index = EXCP_EXT_INTERRUPT;
460 env->error_code = 0;
461 do_interrupt(env);
462 next_tb = 0;
463 }
464#elif defined(TARGET_SPARC)
465 if (interrupt_request & CPU_INTERRUPT_HARD) {
466 if (cpu_interrupts_enabled(env) &&
467 env->interrupt_index > 0) {
468 int pil = env->interrupt_index & 0xf;
469 int type = env->interrupt_index & 0xf0;
470
471 if (((type == TT_EXTINT) &&
472 cpu_pil_allowed(env, pil)) ||
473 type != TT_EXTINT) {
474 env->exception_index = env->interrupt_index;
475 do_interrupt(env);
476 next_tb = 0;
477 }
478 }
479 } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
480
481 env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
482 }
483#elif defined(TARGET_ARM)
484 if (interrupt_request & CPU_INTERRUPT_FIQ
485 && !(env->uncached_cpsr & CPSR_F)) {
486 env->exception_index = EXCP_FIQ;
487 do_interrupt(env);
488 next_tb = 0;
489 }
490
491
492
493
494
495
496
497
498
499 if (interrupt_request & CPU_INTERRUPT_HARD
500 && ((IS_M(env) && env->regs[15] < 0xfffffff0)
501 || !(env->uncached_cpsr & CPSR_I))) {
502 env->exception_index = EXCP_IRQ;
503 do_interrupt(env);
504 next_tb = 0;
505 }
506#elif defined(TARGET_SH4)
507 if (interrupt_request & CPU_INTERRUPT_HARD) {
508 do_interrupt(env);
509 next_tb = 0;
510 }
511#elif defined(TARGET_ALPHA)
512 if (interrupt_request & CPU_INTERRUPT_HARD) {
513 do_interrupt(env);
514 next_tb = 0;
515 }
516#elif defined(TARGET_CRIS)
517 if (interrupt_request & CPU_INTERRUPT_HARD
518 && (env->pregs[PR_CCS] & I_FLAG)
519 && !env->locked_irq) {
520 env->exception_index = EXCP_IRQ;
521 do_interrupt(env);
522 next_tb = 0;
523 }
524 if (interrupt_request & CPU_INTERRUPT_NMI
525 && (env->pregs[PR_CCS] & M_FLAG)) {
526 env->exception_index = EXCP_NMI;
527 do_interrupt(env);
528 next_tb = 0;
529 }
530#elif defined(TARGET_M68K)
531 if (interrupt_request & CPU_INTERRUPT_HARD
532 && ((env->sr & SR_I) >> SR_I_SHIFT)
533 < env->pending_level) {
534
535
536
537
538
539 env->exception_index = env->pending_vector;
540 do_interrupt(1);
541 next_tb = 0;
542 }
543#endif
544
545
546 if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
547 env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
548
549
550 next_tb = 0;
551 }
552 }
553 if (unlikely(env->exit_request)) {
554 env->exit_request = 0;
555 env->exception_index = EXCP_INTERRUPT;
556 cpu_loop_exit();
557 }
558#if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC)
559 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
560
561#if defined(TARGET_I386)
562 env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
563 log_cpu_state(env, X86_DUMP_CCOP);
564 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
565#elif defined(TARGET_M68K)
566 cpu_m68k_flush_flags(env, env->cc_op);
567 env->cc_op = CC_OP_FLAGS;
568 env->sr = (env->sr & 0xffe0)
569 | env->cc_dest | (env->cc_x << 4);
570 log_cpu_state(env, 0);
571#else
572 log_cpu_state(env, 0);
573#endif
574 }
575#endif
576 spin_lock(&tb_lock);
577 tb = tb_find_fast();
578
579
580 if (tb_invalidated_flag) {
581
582
583
584 next_tb = 0;
585 tb_invalidated_flag = 0;
586 }
587#ifdef CONFIG_DEBUG_EXEC
588 qemu_log_mask(CPU_LOG_EXEC, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
589 (long)tb->tc_ptr, tb->pc,
590 lookup_symbol(tb->pc));
591#endif
592
593
594
595 if (next_tb != 0 && tb->page_addr[1] == -1) {
596 tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
597 }
598 spin_unlock(&tb_lock);
599
600
601
602
603
604 env->current_tb = tb;
605 barrier();
606 if (likely(!env->exit_request)) {
607 tc_ptr = tb->tc_ptr;
608
609#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
610#undef env
611 env = cpu_single_env;
612#define env cpu_single_env
613#endif
614 next_tb = tcg_qemu_tb_exec(tc_ptr);
615 if ((next_tb & 3) == 2) {
616
617 int insns_left;
618 tb = (TranslationBlock *)(long)(next_tb & ~3);
619
620 cpu_pc_from_tb(env, tb);
621 insns_left = env->icount_decr.u32;
622 if (env->icount_extra && insns_left >= 0) {
623
624 env->icount_extra += insns_left;
625 if (env->icount_extra > 0xffff) {
626 insns_left = 0xffff;
627 } else {
628 insns_left = env->icount_extra;
629 }
630 env->icount_extra -= insns_left;
631 env->icount_decr.u16.low = insns_left;
632 } else {
633 if (insns_left > 0) {
634
635 cpu_exec_nocache(insns_left, tb);
636 }
637 env->exception_index = EXCP_INTERRUPT;
638 next_tb = 0;
639 cpu_loop_exit();
640 }
641 }
642 }
643 env->current_tb = NULL;
644
645
646 }
647 }
648 }
649
650
651#if defined(TARGET_I386)
652
653 env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
654#elif defined(TARGET_ARM)
655
656#elif defined(TARGET_SPARC)
657#elif defined(TARGET_PPC)
658#elif defined(TARGET_M68K)
659 cpu_m68k_flush_flags(env, env->cc_op);
660 env->cc_op = CC_OP_FLAGS;
661 env->sr = (env->sr & 0xffe0)
662 | env->cc_dest | (env->cc_x << 4);
663#elif defined(TARGET_MICROBLAZE)
664#elif defined(TARGET_MIPS)
665#elif defined(TARGET_SH4)
666#elif defined(TARGET_ALPHA)
667#elif defined(TARGET_CRIS)
668#elif defined(TARGET_S390X)
669
670#else
671#error unsupported target CPU
672#endif
673
674
675 barrier();
676 env = (void *) saved_env_reg;
677
678
679 cpu_single_env = NULL;
680 return ret;
681}
682
683
684
685void tb_invalidate_page_range(target_ulong start, target_ulong end)
686{
687
688
689#if 0
690 target_ulong phys_addr;
691 phys_addr = get_phys_addr_code(env, start);
692 tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);
693#endif
694}
695
696#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
697
698void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
699{
700 CPUX86State *saved_env;
701
702 saved_env = env;
703 env = s;
704 if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
705 selector &= 0xffff;
706 cpu_x86_load_seg_cache(env, seg_reg, selector,
707 (selector << 4), 0xffff, 0);
708 } else {
709 helper_load_seg(seg_reg, selector);
710 }
711 env = saved_env;
712}
713
714void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
715{
716 CPUX86State *saved_env;
717
718 saved_env = env;
719 env = s;
720
721 helper_fsave(ptr, data32);
722
723 env = saved_env;
724}
725
726void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
727{
728 CPUX86State *saved_env;
729
730 saved_env = env;
731 env = s;
732
733 helper_frstor(ptr, data32);
734
735 env = saved_env;
736}
737
738#endif
739
740#if !defined(CONFIG_SOFTMMU)
741
742#if defined(TARGET_I386)
743#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code)
744#else
745#define EXCEPTION_ACTION cpu_loop_exit()
746#endif
747
748
749
750
751
752static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
753 int is_write, sigset_t *old_set,
754 void *puc)
755{
756 TranslationBlock *tb;
757 int ret;
758
759 if (cpu_single_env)
760 env = cpu_single_env;
761#if defined(DEBUG_SIGNAL)
762 qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
763 pc, address, is_write, *(unsigned long *)old_set);
764#endif
765
766 if (is_write && page_unprotect(h2g(address), pc, puc)) {
767 return 1;
768 }
769
770
771 ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
772 if (ret < 0)
773 return 0;
774 if (ret == 0)
775 return 1;
776
777 tb = tb_find_pc(pc);
778 if (tb) {
779
780
781 cpu_restore_state(tb, env, pc, puc);
782 }
783
784
785
786 sigprocmask(SIG_SETMASK, old_set, NULL);
787 EXCEPTION_ACTION;
788
789
790 return 1;
791}
792
793#if defined(__i386__)
794
795#if defined(__APPLE__)
796# include <sys/ucontext.h>
797
798# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
799# define TRAP_sig(context) ((context)->uc_mcontext->es.trapno)
800# define ERROR_sig(context) ((context)->uc_mcontext->es.err)
801# define MASK_sig(context) ((context)->uc_sigmask)
802#elif defined (__NetBSD__)
803# include <ucontext.h>
804
805# define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP])
806# define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
807# define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR])
808# define MASK_sig(context) ((context)->uc_sigmask)
809#elif defined (__FreeBSD__) || defined(__DragonFly__)
810# include <ucontext.h>
811
812# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext.mc_eip))
813# define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno)
814# define ERROR_sig(context) ((context)->uc_mcontext.mc_err)
815# define MASK_sig(context) ((context)->uc_sigmask)
816#elif defined(__OpenBSD__)
817# define EIP_sig(context) ((context)->sc_eip)
818# define TRAP_sig(context) ((context)->sc_trapno)
819# define ERROR_sig(context) ((context)->sc_err)
820# define MASK_sig(context) ((context)->sc_mask)
821#else
822# define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP])
823# define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
824# define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
825# define MASK_sig(context) ((context)->uc_sigmask)
826#endif
827
828int cpu_signal_handler(int host_signum, void *pinfo,
829 void *puc)
830{
831 siginfo_t *info = pinfo;
832#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__)
833 ucontext_t *uc = puc;
834#elif defined(__OpenBSD__)
835 struct sigcontext *uc = puc;
836#else
837 struct ucontext *uc = puc;
838#endif
839 unsigned long pc;
840 int trapno;
841
842#ifndef REG_EIP
843
844#define REG_EIP EIP
845#define REG_ERR ERR
846#define REG_TRAPNO TRAPNO
847#endif
848 pc = EIP_sig(uc);
849 trapno = TRAP_sig(uc);
850 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
851 trapno == 0xe ?
852 (ERROR_sig(uc) >> 1) & 1 : 0,
853 &MASK_sig(uc), puc);
854}
855
856#elif defined(__x86_64__)
857
858#ifdef __NetBSD__
859#define PC_sig(context) _UC_MACHINE_PC(context)
860#define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
861#define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR])
862#define MASK_sig(context) ((context)->uc_sigmask)
863#elif defined(__OpenBSD__)
864#define PC_sig(context) ((context)->sc_rip)
865#define TRAP_sig(context) ((context)->sc_trapno)
866#define ERROR_sig(context) ((context)->sc_err)
867#define MASK_sig(context) ((context)->sc_mask)
868#elif defined (__FreeBSD__) || defined(__DragonFly__)
869#include <ucontext.h>
870
871#define PC_sig(context) (*((unsigned long*)&(context)->uc_mcontext.mc_rip))
872#define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno)
873#define ERROR_sig(context) ((context)->uc_mcontext.mc_err)
874#define MASK_sig(context) ((context)->uc_sigmask)
875#else
876#define PC_sig(context) ((context)->uc_mcontext.gregs[REG_RIP])
877#define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
878#define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
879#define MASK_sig(context) ((context)->uc_sigmask)
880#endif
881
882int cpu_signal_handler(int host_signum, void *pinfo,
883 void *puc)
884{
885 siginfo_t *info = pinfo;
886 unsigned long pc;
887#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__)
888 ucontext_t *uc = puc;
889#elif defined(__OpenBSD__)
890 struct sigcontext *uc = puc;
891#else
892 struct ucontext *uc = puc;
893#endif
894
895 pc = PC_sig(uc);
896 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
897 TRAP_sig(uc) == 0xe ?
898 (ERROR_sig(uc) >> 1) & 1 : 0,
899 &MASK_sig(uc), puc);
900}
901
902#elif defined(_ARCH_PPC)
903
904
905
906
907
908#ifdef linux
909
910# define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name)
911
912# define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context)
913# define IAR_sig(context) REG_sig(nip, context)
914# define MSR_sig(context) REG_sig(msr, context)
915# define CTR_sig(context) REG_sig(ctr, context)
916# define XER_sig(context) REG_sig(xer, context)
917# define LR_sig(context) REG_sig(link, context)
918# define CR_sig(context) REG_sig(ccr, context)
919
920# define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
921# define FPSCR_sig(context) (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
922
923# define DAR_sig(context) REG_sig(dar, context)
924# define DSISR_sig(context) REG_sig(dsisr, context)
925# define TRAP_sig(context) REG_sig(trap, context)
926#endif
927
928#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
929#include <ucontext.h>
930# define IAR_sig(context) ((context)->uc_mcontext.mc_srr0)
931# define MSR_sig(context) ((context)->uc_mcontext.mc_srr1)
932# define CTR_sig(context) ((context)->uc_mcontext.mc_ctr)
933# define XER_sig(context) ((context)->uc_mcontext.mc_xer)
934# define LR_sig(context) ((context)->uc_mcontext.mc_lr)
935# define CR_sig(context) ((context)->uc_mcontext.mc_cr)
936
937# define DAR_sig(context) ((context)->uc_mcontext.mc_dar)
938# define DSISR_sig(context) ((context)->uc_mcontext.mc_dsisr)
939# define TRAP_sig(context) ((context)->uc_mcontext.mc_exc)
940#endif
941
942#ifdef __APPLE__
943# include <sys/ucontext.h>
944typedef struct ucontext SIGCONTEXT;
945
946# define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name)
947# define FLOATREG_sig(reg_name, context) ((context)->uc_mcontext->fs.reg_name)
948# define EXCEPREG_sig(reg_name, context) ((context)->uc_mcontext->es.reg_name)
949# define VECREG_sig(reg_name, context) ((context)->uc_mcontext->vs.reg_name)
950
951# define GPR_sig(reg_num, context) REG_sig(r##reg_num, context)
952# define IAR_sig(context) REG_sig(srr0, context)
953# define MSR_sig(context) REG_sig(srr1, context)
954# define CTR_sig(context) REG_sig(ctr, context)
955# define XER_sig(context) REG_sig(xer, context)
956# define LR_sig(context) REG_sig(lr, context)
957# define CR_sig(context) REG_sig(cr, context)
958
959# define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context)
960# define FPSCR_sig(context) ((double)FLOATREG_sig(fpscr, context))
961
962# define DAR_sig(context) EXCEPREG_sig(dar, context)
963# define DSISR_sig(context) EXCEPREG_sig(dsisr, context)
964# define TRAP_sig(context) EXCEPREG_sig(exception, context)
965#endif
966
967int cpu_signal_handler(int host_signum, void *pinfo,
968 void *puc)
969{
970 siginfo_t *info = pinfo;
971#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
972 ucontext_t *uc = puc;
973#else
974 struct ucontext *uc = puc;
975#endif
976 unsigned long pc;
977 int is_write;
978
979 pc = IAR_sig(uc);
980 is_write = 0;
981#if 0
982
983 if (DSISR_sig(uc) & 0x00800000)
984 is_write = 1;
985#else
986 if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
987 is_write = 1;
988#endif
989 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
990 is_write, &uc->uc_sigmask, puc);
991}
992
993#elif defined(__alpha__)
994
995int cpu_signal_handler(int host_signum, void *pinfo,
996 void *puc)
997{
998 siginfo_t *info = pinfo;
999 struct ucontext *uc = puc;
1000 uint32_t *pc = uc->uc_mcontext.sc_pc;
1001 uint32_t insn = *pc;
1002 int is_write = 0;
1003
1004
1005 switch (insn >> 26) {
1006 case 0x0d:
1007 case 0x0e:
1008 case 0x0f:
1009 case 0x24:
1010 case 0x25:
1011 case 0x26:
1012 case 0x27:
1013 case 0x2c:
1014 case 0x2d:
1015 case 0x2e:
1016 case 0x2f:
1017 is_write = 1;
1018 }
1019
1020 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1021 is_write, &uc->uc_sigmask, puc);
1022}
1023#elif defined(__sparc__)
1024
1025int cpu_signal_handler(int host_signum, void *pinfo,
1026 void *puc)
1027{
1028 siginfo_t *info = pinfo;
1029 int is_write;
1030 uint32_t insn;
1031#if !defined(__arch64__) || defined(CONFIG_SOLARIS)
1032 uint32_t *regs = (uint32_t *)(info + 1);
1033 void *sigmask = (regs + 20);
1034
1035 unsigned long pc = regs[1];
1036#else
1037#ifdef __linux__
1038 struct sigcontext *sc = puc;
1039 unsigned long pc = sc->sigc_regs.tpc;
1040 void *sigmask = (void *)sc->sigc_mask;
1041#elif defined(__OpenBSD__)
1042 struct sigcontext *uc = puc;
1043 unsigned long pc = uc->sc_pc;
1044 void *sigmask = (void *)(long)uc->sc_mask;
1045#endif
1046#endif
1047
1048
1049 is_write = 0;
1050 insn = *(uint32_t *)pc;
1051 if ((insn >> 30) == 3) {
1052 switch((insn >> 19) & 0x3f) {
1053 case 0x05:
1054 case 0x15:
1055 case 0x06:
1056 case 0x16:
1057 case 0x04:
1058 case 0x14:
1059 case 0x07:
1060 case 0x17:
1061 case 0x0e:
1062 case 0x1e:
1063 case 0x24:
1064 case 0x34:
1065 case 0x27:
1066 case 0x37:
1067 case 0x26:
1068 case 0x36:
1069 case 0x25:
1070 case 0x3c:
1071 case 0x3e:
1072 is_write = 1;
1073 break;
1074 }
1075 }
1076 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1077 is_write, sigmask, NULL);
1078}
1079
1080#elif defined(__arm__)
1081
1082int cpu_signal_handler(int host_signum, void *pinfo,
1083 void *puc)
1084{
1085 siginfo_t *info = pinfo;
1086 struct ucontext *uc = puc;
1087 unsigned long pc;
1088 int is_write;
1089
1090#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
1091 pc = uc->uc_mcontext.gregs[R15];
1092#else
1093 pc = uc->uc_mcontext.arm_pc;
1094#endif
1095
1096 is_write = 0;
1097 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1098 is_write,
1099 &uc->uc_sigmask, puc);
1100}
1101
1102#elif defined(__mc68000)
1103
1104int cpu_signal_handler(int host_signum, void *pinfo,
1105 void *puc)
1106{
1107 siginfo_t *info = pinfo;
1108 struct ucontext *uc = puc;
1109 unsigned long pc;
1110 int is_write;
1111
1112 pc = uc->uc_mcontext.gregs[16];
1113
1114 is_write = 0;
1115 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1116 is_write,
1117 &uc->uc_sigmask, puc);
1118}
1119
1120#elif defined(__ia64)
1121
1122#ifndef __ISR_VALID
1123
1124# define __ISR_VALID 1
1125#endif
1126
1127int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
1128{
1129 siginfo_t *info = pinfo;
1130 struct ucontext *uc = puc;
1131 unsigned long ip;
1132 int is_write = 0;
1133
1134 ip = uc->uc_mcontext.sc_ip;
1135 switch (host_signum) {
1136 case SIGILL:
1137 case SIGFPE:
1138 case SIGSEGV:
1139 case SIGBUS:
1140 case SIGTRAP:
1141 if (info->si_code && (info->si_segvflags & __ISR_VALID))
1142
1143 is_write = (info->si_isr >> 33) & 1;
1144 break;
1145
1146 default:
1147 break;
1148 }
1149 return handle_cpu_signal(ip, (unsigned long)info->si_addr,
1150 is_write,
1151 (sigset_t *)&uc->uc_sigmask, puc);
1152}
1153
1154#elif defined(__s390__)
1155
1156int cpu_signal_handler(int host_signum, void *pinfo,
1157 void *puc)
1158{
1159 siginfo_t *info = pinfo;
1160 struct ucontext *uc = puc;
1161 unsigned long pc;
1162 uint16_t *pinsn;
1163 int is_write = 0;
1164
1165 pc = uc->uc_mcontext.psw.addr;
1166
1167
1168
1169
1170
1171
1172
1173
1174 pinsn = (uint16_t *)pc;
1175 switch (pinsn[0] >> 8) {
1176 case 0x50:
1177 case 0x42:
1178 case 0x40:
1179 is_write = 1;
1180 break;
1181 case 0xc4:
1182 switch (pinsn[0] & 0xf) {
1183 case 0xf:
1184 case 0xb:
1185 case 0x7:
1186 is_write = 1;
1187 }
1188 break;
1189 case 0xe3:
1190 switch (pinsn[2] & 0xff) {
1191 case 0x50:
1192 case 0x24:
1193 case 0x72:
1194 case 0x70:
1195 case 0x8e:
1196 case 0x3f:
1197 case 0x3e:
1198 case 0x2f:
1199 is_write = 1;
1200 }
1201 break;
1202 }
1203 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1204 is_write, &uc->uc_sigmask, puc);
1205}
1206
1207#elif defined(__mips__)
1208
1209int cpu_signal_handler(int host_signum, void *pinfo,
1210 void *puc)
1211{
1212 siginfo_t *info = pinfo;
1213 struct ucontext *uc = puc;
1214 greg_t pc = uc->uc_mcontext.pc;
1215 int is_write;
1216
1217
1218 is_write = 0;
1219 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1220 is_write, &uc->uc_sigmask, puc);
1221}
1222
1223#elif defined(__hppa__)
1224
1225int cpu_signal_handler(int host_signum, void *pinfo,
1226 void *puc)
1227{
1228 struct siginfo *info = pinfo;
1229 struct ucontext *uc = puc;
1230 unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
1231 uint32_t insn = *(uint32_t *)pc;
1232 int is_write = 0;
1233
1234
1235 switch (insn >> 26) {
1236 case 0x1a:
1237 case 0x19:
1238 case 0x18:
1239 case 0x1b:
1240 is_write = 1;
1241 break;
1242
1243 case 0x09:
1244 case 0x0b:
1245
1246 is_write = (insn >> 9) & 1;
1247 break;
1248
1249 case 0x03:
1250 switch ((insn >> 6) & 15) {
1251 case 0xa:
1252 case 0x9:
1253 case 0x8:
1254 case 0xe:
1255 case 0xc:
1256 is_write = 1;
1257 }
1258 break;
1259 }
1260
1261 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1262 is_write, &uc->uc_sigmask, puc);
1263}
1264
1265#else
1266
1267#error host CPU specific signal handler needed
1268
1269#endif
1270
1271#endif
1272