1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include "qemu/osdep.h"
20#include "cpu.h"
21#include "trace.h"
22#include "disas/disas.h"
23#include "tcg.h"
24#include "qemu/atomic.h"
25#include "sysemu/qtest.h"
26#include "qemu/timer.h"
27#include "exec/address-spaces.h"
28#include "qemu/rcu.h"
29#include "exec/tb-hash.h"
30#include "exec/log.h"
31#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
32#include "hw/i386/apic.h"
33#endif
34#include "sysemu/replay.h"
35#include "qemu/etrace.h"
36
37
38
39typedef struct SyncClocks {
40 int64_t diff_clk;
41 int64_t last_cpu_icount;
42 int64_t realtime_clock;
43} SyncClocks;
44
45#if !defined(CONFIG_USER_ONLY)
46
47
48
49
50#define VM_CLOCK_ADVANCE 3000000
51#define THRESHOLD_REDUCE 1.5
52#define MAX_DELAY_PRINT_RATE 2000000000LL
53#define MAX_NB_PRINTS 100
54
55static void align_clocks(SyncClocks *sc, const CPUState *cpu)
56{
57 int64_t cpu_icount;
58
59 if (!icount_align_option) {
60 return;
61 }
62
63 cpu_icount = cpu->icount_extra + cpu->icount_decr.u16.low;
64 sc->diff_clk += cpu_icount_to_ns(sc->last_cpu_icount - cpu_icount);
65 sc->last_cpu_icount = cpu_icount;
66
67 if (sc->diff_clk > VM_CLOCK_ADVANCE) {
68#ifndef _WIN32
69 struct timespec sleep_delay, rem_delay;
70 sleep_delay.tv_sec = sc->diff_clk / 1000000000LL;
71 sleep_delay.tv_nsec = sc->diff_clk % 1000000000LL;
72 if (nanosleep(&sleep_delay, &rem_delay) < 0) {
73 sc->diff_clk = rem_delay.tv_sec * 1000000000LL + rem_delay.tv_nsec;
74 } else {
75 sc->diff_clk = 0;
76 }
77#else
78 Sleep(sc->diff_clk / SCALE_MS);
79 sc->diff_clk = 0;
80#endif
81 }
82}
83
84static void print_delay(const SyncClocks *sc)
85{
86 static float threshold_delay;
87 static int64_t last_realtime_clock;
88 static int nb_prints;
89
90 if (icount_align_option &&
91 sc->realtime_clock - last_realtime_clock >= MAX_DELAY_PRINT_RATE &&
92 nb_prints < MAX_NB_PRINTS) {
93 if ((-sc->diff_clk / (float)1000000000LL > threshold_delay) ||
94 (-sc->diff_clk / (float)1000000000LL <
95 (threshold_delay - THRESHOLD_REDUCE))) {
96 threshold_delay = (-sc->diff_clk / 1000000000LL) + 1;
97 printf("Warning: The guest is now late by %.1f to %.1f seconds\n",
98 threshold_delay - 1,
99 threshold_delay);
100 nb_prints++;
101 last_realtime_clock = sc->realtime_clock;
102 }
103 }
104}
105
106static void init_delay_params(SyncClocks *sc,
107 const CPUState *cpu)
108{
109 if (!icount_align_option) {
110 return;
111 }
112 sc->realtime_clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT);
113 sc->diff_clk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - sc->realtime_clock;
114 sc->last_cpu_icount = cpu->icount_extra + cpu->icount_decr.u16.low;
115 if (sc->diff_clk < max_delay) {
116 max_delay = sc->diff_clk;
117 }
118 if (sc->diff_clk > max_advance) {
119 max_advance = sc->diff_clk;
120 }
121
122
123
124 print_delay(sc);
125}
126#else
127static void align_clocks(SyncClocks *sc, const CPUState *cpu)
128{
129}
130
131static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
132{
133}
134#endif
135
136
137static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
138{
139 CPUArchState *env = cpu->env_ptr;
140 uintptr_t next_tb;
141 uint8_t *tb_ptr = itb->tc_ptr;
142
143 qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
144 "CPU%d Trace %p [" TARGET_FMT_lx "] %s\n",
145 cpu->cpu_index,
146 itb->tc_ptr, itb->pc, lookup_symbol(itb->pc));
147
148 if (qemu_etrace_mask(ETRACE_F_CPU)) {
149
150
151 qemu_etracer.current_unit_id = cpu->cpu_index;
152 cpu_dump_state(cpu, (void *) &qemu_etracer,
153 etrace_note_fprintf, 0);
154 }
155 if (qemu_etrace_mask(ETRACE_F_EXEC)) {
156 etrace_dump_exec_start(&qemu_etracer, cpu->cpu_index,
157 itb->pc);
158 }
159
160
161#if defined(DEBUG_DISAS)
162 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
163#if defined(TARGET_I386)
164 log_cpu_state(cpu, CPU_DUMP_CCOP);
165#elif defined(TARGET_M68K)
166
167 cpu_m68k_flush_flags(env, env->cc_op);
168 env->cc_op = CC_OP_FLAGS;
169 env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4);
170 log_cpu_state(cpu, 0);
171#else
172 log_cpu_state(cpu, 0);
173#endif
174 }
175#endif
176
177 cpu->can_do_io = !use_icount;
178 next_tb = tcg_qemu_tb_exec(env, tb_ptr);
179 cpu->can_do_io = 1;
180 trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK),
181 next_tb & TB_EXIT_MASK);
182
183 if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
184
185
186
187
188 CPUClass *cc = CPU_GET_CLASS(cpu);
189 TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
190 qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
191 "Stopped execution of TB chain before %p ["
192 TARGET_FMT_lx "] %s\n",
193 itb->tc_ptr, itb->pc, lookup_symbol(itb->pc));
194 if (cc->synchronize_from_tb) {
195 cc->synchronize_from_tb(cpu, tb);
196 } else {
197 assert(cc->set_pc);
198 cc->set_pc(cpu, tb->pc);
199 }
200 }
201 if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
202
203
204
205 cpu->tcg_exit_req = 0;
206 }
207 return next_tb;
208}
209
210
211
212static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
213 TranslationBlock *orig_tb, bool ignore_icount)
214{
215 TranslationBlock *tb;
216
217
218
219 if (max_cycles > CF_COUNT_MASK)
220 max_cycles = CF_COUNT_MASK;
221
222 tb = tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
223 max_cycles | CF_NOCACHE
224 | (ignore_icount ? CF_IGNORE_ICOUNT : 0));
225 tb->orig_tb = tcg_ctx.tb_ctx.tb_invalidated_flag ? NULL : orig_tb;
226 cpu->current_tb = tb;
227
228 trace_exec_tb_nocache(tb, tb->pc);
229 cpu_tb_exec(cpu, tb);
230 cpu->current_tb = NULL;
231 tb_phys_invalidate(tb, -1);
232 tb_free(tb);
233}
234
235static TranslationBlock *tb_find_physical(CPUState *cpu,
236 target_ulong pc,
237 target_ulong cs_base,
238 uint64_t flags)
239{
240 CPUArchState *env = (CPUArchState *)cpu->env_ptr;
241 TranslationBlock *tb, **ptb1;
242 unsigned int h;
243 tb_page_addr_t phys_pc, phys_page1;
244 target_ulong virt_page2;
245
246 tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
247
248
249 phys_pc = get_page_addr_code(env, pc);
250 phys_page1 = phys_pc & TARGET_PAGE_MASK;
251 h = tb_phys_hash_func(phys_pc);
252 ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
253 for(;;) {
254 tb = *ptb1;
255 if (!tb) {
256 return NULL;
257 }
258 if (tb->pc == pc &&
259 tb->page_addr[0] == phys_page1 &&
260 tb->cs_base == cs_base &&
261 tb->flags == flags) {
262
263 if (tb->page_addr[1] != -1) {
264 tb_page_addr_t phys_page2;
265
266 virt_page2 = (pc & TARGET_PAGE_MASK) +
267 TARGET_PAGE_SIZE;
268 phys_page2 = get_page_addr_code(env, virt_page2);
269 if (tb->page_addr[1] == phys_page2) {
270 break;
271 }
272 } else {
273 break;
274 }
275 }
276 ptb1 = &tb->phys_hash_next;
277 }
278
279
280 *ptb1 = tb->phys_hash_next;
281 tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
282 tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
283 return tb;
284}
285
286static TranslationBlock *tb_find_slow(CPUState *cpu,
287 target_ulong pc,
288 target_ulong cs_base,
289 uint64_t flags)
290{
291 TranslationBlock *tb;
292
293 tb = tb_find_physical(cpu, pc, cs_base, flags);
294 if (tb) {
295 goto found;
296 }
297
298#ifdef CONFIG_USER_ONLY
299
300
301
302
303
304 tb_unlock();
305 mmap_lock();
306 tb_lock();
307 tb = tb_find_physical(cpu, pc, cs_base, flags);
308 if (tb) {
309 mmap_unlock();
310 goto found;
311 }
312#endif
313
314
315 tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
316
317#ifdef CONFIG_USER_ONLY
318 mmap_unlock();
319#endif
320
321found:
322
323 cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
324 return tb;
325}
326
327static inline TranslationBlock *tb_find_fast(CPUState *cpu)
328{
329 CPUArchState *env = (CPUArchState *)cpu->env_ptr;
330 TranslationBlock *tb;
331 target_ulong cs_base, pc;
332 int flags;
333
334
335
336
337 cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
338 tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
339 if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
340 tb->flags != flags)) {
341 tb = tb_find_slow(cpu, pc, cs_base, flags);
342 }
343 return tb;
344}
345
346static void cpu_handle_debug_exception(CPUState *cpu)
347{
348 CPUClass *cc = CPU_GET_CLASS(cpu);
349 CPUWatchpoint *wp;
350
351 if (!cpu->watchpoint_hit) {
352 QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
353 wp->flags &= ~BP_WATCHPOINT_HIT;
354 }
355 }
356
357 cc->debug_excp_handler(cpu);
358}
359
360
361
362int cpu_exec(CPUState *cpu)
363{
364 CPUClass *cc = CPU_GET_CLASS(cpu);
365#ifdef TARGET_I386
366 X86CPU *x86_cpu = X86_CPU(cpu);
367 CPUArchState *env = &x86_cpu->env;
368#else
369 CPUArchState *env = (CPUArchState *)cpu->env_ptr;
370#endif
371 int ret, interrupt_request;
372 TranslationBlock *tb;
373 uintptr_t next_tb;
374 SyncClocks sc;
375
376
377 current_cpu = cpu;
378
379 if (cpu->halted) {
380#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
381 if ((cpu->interrupt_request & CPU_INTERRUPT_POLL)
382 && replay_interrupt()) {
383 apic_poll_irq(x86_cpu->apic_state);
384 cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
385 }
386#endif
387 if (qemu_etrace_mask(ETRACE_F_EXEC)) {
388 const char *dev_name = object_get_canonical_path(OBJECT(cpu));
389 etrace_event_u64(&qemu_etracer, cpu->cpu_index,
390 ETRACE_EVU64_F_PREV_VAL,
391 dev_name, "sleep", 0, 1);
392 }
393
394 if (!cpu_has_work(cpu)) {
395 current_cpu = NULL;
396 return EXCP_HALTED;
397 }
398
399 cpu->halted = 0;
400 }
401
402 atomic_mb_set(&tcg_current_cpu, cpu);
403 rcu_read_lock();
404
405 if (unlikely(atomic_mb_read(&exit_request))) {
406 cpu->exit_request = 1;
407 }
408
409 cc->cpu_exec_enter(cpu);
410
411
412
413
414
415
416 init_delay_params(&sc, cpu);
417
418
419 for(;;) {
420 if (sigsetjmp(cpu->jmp_env, 0) == 0) {
421
422 if (cpu->exception_index >= 0) {
423 if (cpu->exception_index >= EXCP_INTERRUPT) {
424
425 ret = cpu->exception_index;
426 if (ret == EXCP_DEBUG) {
427 cpu_handle_debug_exception(cpu);
428 }
429 cpu->exception_index = -1;
430 break;
431 } else {
432#if defined(CONFIG_USER_ONLY)
433
434
435
436#if defined(TARGET_I386)
437 cc->do_interrupt(cpu);
438#endif
439 ret = cpu->exception_index;
440 cpu->exception_index = -1;
441 break;
442#else
443 if (replay_exception()) {
444 cc->do_interrupt(cpu);
445 cpu->exception_index = -1;
446 } else if (!replay_has_interrupt()) {
447
448 ret = EXCP_INTERRUPT;
449 break;
450 }
451#endif
452 }
453 } else if (replay_has_exception()
454 && cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
455
456 cpu_exec_nocache(cpu, 1, tb_find_fast(cpu), true);
457 ret = -1;
458 break;
459 }
460
461 next_tb = 0;
462 for(;;) {
463 interrupt_request = cpu->interrupt_request;
464 if (unlikely(interrupt_request)) {
465 if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
466
467 interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
468 }
469 if (interrupt_request & CPU_INTERRUPT_DEBUG) {
470 cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
471 cpu->exception_index = EXCP_DEBUG;
472 cpu_loop_exit(cpu);
473 }
474 if (replay_mode == REPLAY_MODE_PLAY
475 && !replay_has_interrupt()) {
476
477 } else if (interrupt_request & CPU_INTERRUPT_HALT) {
478 replay_interrupt();
479 cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
480 cpu->halted = 1;
481 cpu->exception_index = EXCP_HLT;
482 cpu_loop_exit(cpu);
483 }
484#if defined(TARGET_I386)
485 else if (interrupt_request & CPU_INTERRUPT_INIT) {
486 replay_interrupt();
487 cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0);
488 do_cpu_init(x86_cpu);
489 cpu->exception_index = EXCP_HALTED;
490 cpu_loop_exit(cpu);
491 }
492#else
493 else if (interrupt_request & CPU_INTERRUPT_RESET) {
494 replay_interrupt();
495 cpu_reset(cpu);
496 cpu_loop_exit(cpu);
497 }
498#endif
499
500
501
502
503 else {
504 replay_interrupt();
505 if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
506 next_tb = 0;
507 }
508 }
509
510
511 if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
512 cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
513
514
515 next_tb = 0;
516 }
517 }
518 if (unlikely(cpu->exit_request
519 || replay_has_interrupt())) {
520 cpu->exit_request = 0;
521 cpu->exception_index = EXCP_INTERRUPT;
522 cpu_loop_exit(cpu);
523 }
524 tb_lock();
525 tb = tb_find_fast(cpu);
526
527
528 if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
529
530
531
532 next_tb = 0;
533 tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
534 }
535
536
537
538 if (next_tb != 0 && tb->page_addr[1] == -1
539 && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
540 tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
541 next_tb & TB_EXIT_MASK, tb);
542 }
543 tb_unlock();
544 if (likely(!cpu->exit_request)) {
545 bool tb_exit = false;
546 trace_exec_tb(tb, tb->pc);
547
548 cpu->current_tb = tb;
549 next_tb = cpu_tb_exec(cpu, tb);
550 cpu->current_tb = NULL;
551 switch (next_tb & TB_EXIT_MASK) {
552 case TB_EXIT_REQUESTED:
553
554
555
556
557
558
559
560
561
562
563 smp_rmb();
564 next_tb = 0;
565 tb_exit = true;
566 break;
567 case TB_EXIT_ICOUNT_EXPIRED:
568 {
569
570 int insns_left = cpu->icount_decr.u32;
571 if (cpu->icount_extra && insns_left >= 0) {
572
573 cpu->icount_extra += insns_left;
574 insns_left = MIN(0xffff, cpu->icount_extra);
575 cpu->icount_extra -= insns_left;
576 cpu->icount_decr.u16.low = insns_left;
577 } else {
578 if (insns_left > 0) {
579
580 tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
581 cpu_exec_nocache(cpu, insns_left, tb, false);
582 align_clocks(&sc, cpu);
583 }
584 cpu->exception_index = EXCP_INTERRUPT;
585 next_tb = 0;
586 cpu_loop_exit(cpu);
587 }
588 tb_exit = true;
589 break;
590 }
591 default:
592 tb_exit = false;
593 break;
594 }
595 if (qemu_etrace_mask(ETRACE_F_EXEC)) {
596 target_ulong cs_base, pc;
597 int flags;
598
599 if (tb_exit) {
600
601 cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
602 } else {
603
604 pc = tb->pc + tb->size;
605 }
606 etrace_dump_exec_end(&qemu_etracer,
607 cpu->cpu_index, pc);
608 }
609 }
610 qemu_etracer.exec_start_valid = false;
611
612
613 align_clocks(&sc, cpu);
614
615
616 }
617 } else {
618#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
619
620
621
622
623 cpu = current_cpu;
624 cc = CPU_GET_CLASS(cpu);
625#ifdef TARGET_I386
626 x86_cpu = X86_CPU(cpu);
627 env = &x86_cpu->env;
628#endif
629#else
630
631 g_assert(cpu == current_cpu);
632 g_assert(cc == CPU_GET_CLASS(cpu));
633#ifdef TARGET_I386
634 g_assert(x86_cpu == X86_CPU(cpu));
635 g_assert(env == &x86_cpu->env);
636#endif
637#endif
638 if (qemu_etrace_mask(ETRACE_F_EXEC)
639 && qemu_etracer.exec_start_valid) {
640 target_ulong cs_base, pc;
641 int flags;
642
643 cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
644 etrace_dump_exec_end(&qemu_etracer, cpu->cpu_index, pc);
645 }
646
647 cpu->can_do_io = 1;
648 tb_lock_reset();
649 }
650 }
651
652 cc->cpu_exec_exit(cpu);
653 rcu_read_unlock();
654
655
656 current_cpu = NULL;
657
658
659 atomic_set(&tcg_current_cpu, NULL);
660 return ret;
661}
662