1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#ifdef _WIN32
20#include <windows.h>
21#endif
22#include "qemu/osdep.h"
23
24
25#include "qemu-common.h"
26#define NO_CPU_IO_DEFS
27#include "cpu.h"
28#include "trace.h"
29#include "disas/disas.h"
30#include "exec/exec-all.h"
31#include "tcg.h"
32#if defined(CONFIG_USER_ONLY)
33#include "qemu.h"
34#include "exec/exec-all.h"
35#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
36#include <sys/param.h>
37#if __FreeBSD_version >= 700104
38#define HAVE_KINFO_GETVMMAP
39#define sigqueue sigqueue_freebsd
40#include <sys/proc.h>
41#include <machine/profile.h>
42#define _KERNEL
43#include <sys/user.h>
44#undef _KERNEL
45#undef sigqueue
46#include <libutil.h>
47#endif
48#endif
49#else
50#include "exec/address-spaces.h"
51#endif
52
53#include "exec/cputlb.h"
54#include "exec/tb-hash.h"
55#include "translate-all.h"
56#include "qemu/bitmap.h"
57#include "qemu/timer.h"
58#include "exec/log.h"
59#include "qemu/etrace.h"
60
61
62
63
64
65
66
67#if !defined(CONFIG_USER_ONLY)
68
69#undef DEBUG_TB_CHECK
70#endif
71
72
73
74
75
76
77
78#ifdef DEBUG_LOCKING
79#define DEBUG_MEM_LOCKS 1
80#else
81#define DEBUG_MEM_LOCKS 0
82#endif
83
84#ifdef CONFIG_SOFTMMU
85#define assert_memory_lock() do { } while (0)
86#else
87#define assert_memory_lock() do { \
88 if (DEBUG_MEM_LOCKS) { \
89 g_assert(have_mmap_lock()); \
90 } \
91 } while (0)
92#endif
93
94#define SMC_BITMAP_USE_THRESHOLD 10
95
96typedef struct PageDesc {
97
98 TranslationBlock *first_tb;
99#ifdef CONFIG_SOFTMMU
100
101
102 unsigned int code_write_count;
103 unsigned long *code_bitmap;
104#else
105 unsigned long flags;
106#endif
107} PageDesc;
108
109
110
111#if !defined(CONFIG_USER_ONLY)
112#if HOST_LONG_BITS < TARGET_PHYS_ADDR_SPACE_BITS
113# define L1_MAP_ADDR_SPACE_BITS HOST_LONG_BITS
114#else
115# define L1_MAP_ADDR_SPACE_BITS TARGET_PHYS_ADDR_SPACE_BITS
116#endif
117#else
118# define L1_MAP_ADDR_SPACE_BITS TARGET_VIRT_ADDR_SPACE_BITS
119#endif
120
121
122#define V_L2_BITS 10
123#define V_L2_SIZE (1 << V_L2_BITS)
124
125uintptr_t qemu_host_page_size;
126intptr_t qemu_host_page_mask;
127
128
129
130
131static int v_l1_size;
132static int v_l1_shift;
133static int v_l2_levels;
134
135
136
137
138#define V_L1_MIN_BITS 4
139#define V_L1_MAX_BITS (V_L2_BITS + 3)
140#define V_L1_MAX_SIZE (1 << V_L1_MAX_BITS)
141
142static void *l1_map[V_L1_MAX_SIZE];
143
144
145TCGContext tcg_ctx;
146bool parallel_cpus;
147
148
149#ifdef CONFIG_USER_ONLY
150__thread int have_tb_lock;
151#endif
152
153static void page_table_config_init(void)
154{
155 uint32_t v_l1_bits;
156
157 assert(TARGET_PAGE_BITS);
158
159 v_l1_bits = (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS) % V_L2_BITS;
160 if (v_l1_bits < V_L1_MIN_BITS) {
161 v_l1_bits += V_L2_BITS;
162 }
163
164 v_l1_size = 1 << v_l1_bits;
165 v_l1_shift = L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - v_l1_bits;
166 v_l2_levels = v_l1_shift / V_L2_BITS - 1;
167
168 assert(v_l1_bits <= V_L1_MAX_BITS);
169 assert(v_l1_shift % V_L2_BITS == 0);
170 assert(v_l2_levels >= 0);
171}
172
173void tb_lock(void)
174{
175#ifdef CONFIG_USER_ONLY
176 assert(!have_tb_lock);
177 qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
178 have_tb_lock++;
179#endif
180}
181
182void tb_unlock(void)
183{
184#ifdef CONFIG_USER_ONLY
185 assert(have_tb_lock);
186 have_tb_lock--;
187 qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
188#endif
189}
190
191void tb_lock_reset(void)
192{
193#ifdef CONFIG_USER_ONLY
194 if (have_tb_lock) {
195 qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
196 have_tb_lock = 0;
197 }
198#endif
199}
200
201#ifdef DEBUG_LOCKING
202#define DEBUG_TB_LOCKS 1
203#else
204#define DEBUG_TB_LOCKS 0
205#endif
206
207#ifdef CONFIG_SOFTMMU
208#define assert_tb_lock() do { } while (0)
209#else
210#define assert_tb_lock() do { \
211 if (DEBUG_TB_LOCKS) { \
212 g_assert(have_tb_lock); \
213 } \
214 } while (0)
215#endif
216
217
218static TranslationBlock *tb_find_pc(uintptr_t tc_ptr);
219
220void cpu_gen_init(void)
221{
222 tcg_context_init(&tcg_ctx);
223}
224
225
226
227static uint8_t *encode_sleb128(uint8_t *p, target_long val)
228{
229 int more, byte;
230
231 do {
232 byte = val & 0x7f;
233 val >>= 7;
234 more = !((val == 0 && (byte & 0x40) == 0)
235 || (val == -1 && (byte & 0x40) != 0));
236 if (more) {
237 byte |= 0x80;
238 }
239 *p++ = byte;
240 } while (more);
241
242 return p;
243}
244
245
246
247static target_long decode_sleb128(uint8_t **pp)
248{
249 uint8_t *p = *pp;
250 target_long val = 0;
251 int byte, shift = 0;
252
253 do {
254 byte = *p++;
255 val |= (target_ulong)(byte & 0x7f) << shift;
256 shift += 7;
257 } while (byte & 0x80);
258 if (shift < TARGET_LONG_BITS && (byte & 0x40)) {
259 val |= -(target_ulong)1 << shift;
260 }
261
262 *pp = p;
263 return val;
264}
265
266
267
268
269
270
271
272
273
274
275
276
277
278static int encode_search(TranslationBlock *tb, uint8_t *block)
279{
280 uint8_t *highwater = tcg_ctx.code_gen_highwater;
281 uint8_t *p = block;
282 int i, j, n;
283
284 tb->tc_search = block;
285
286 for (i = 0, n = tb->icount; i < n; ++i) {
287 target_ulong prev;
288
289 for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
290 if (i == 0) {
291 prev = (j == 0 ? tb->pc : 0);
292 } else {
293 prev = tcg_ctx.gen_insn_data[i - 1][j];
294 }
295 p = encode_sleb128(p, tcg_ctx.gen_insn_data[i][j] - prev);
296 }
297 prev = (i == 0 ? 0 : tcg_ctx.gen_insn_end_off[i - 1]);
298 p = encode_sleb128(p, tcg_ctx.gen_insn_end_off[i] - prev);
299
300
301
302
303
304 if (unlikely(p > highwater)) {
305 return -1;
306 }
307 }
308
309 return p - block;
310}
311
312
313
314
315static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
316 uintptr_t searched_pc)
317{
318 target_ulong data[TARGET_INSN_START_WORDS] = { tb->pc };
319 uintptr_t host_pc = (uintptr_t)tb->tc_ptr;
320 CPUArchState *env = cpu->env_ptr;
321 uint8_t *p = tb->tc_search;
322 int i, j, num_insns = tb->icount;
323#ifdef CONFIG_PROFILER
324 int64_t ti = profile_getclock();
325#endif
326
327 searched_pc -= GETPC_ADJ;
328
329 if (searched_pc < host_pc) {
330 return -1;
331 }
332
333
334
335 for (i = 0; i < num_insns; ++i) {
336 for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
337 data[j] += decode_sleb128(&p);
338 }
339 host_pc += decode_sleb128(&p);
340 if (host_pc > searched_pc) {
341 goto found;
342 }
343 }
344 return -1;
345
346 found:
347 if (tb->cflags & CF_USE_ICOUNT) {
348 assert(use_icount);
349
350 cpu->icount_decr.u16.low += num_insns;
351
352 cpu->can_do_io = 0;
353 }
354 cpu->icount_decr.u16.low -= i;
355 restore_state_to_opc(env, tb, data);
356
357#ifdef CONFIG_PROFILER
358 tcg_ctx.restore_time += profile_getclock() - ti;
359 tcg_ctx.restore_count++;
360#endif
361 return 0;
362}
363
364bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
365{
366 TranslationBlock *tb;
367 bool r = false;
368
369 tb_lock();
370 tb = tb_find_pc(retaddr);
371 if (tb) {
372 cpu_restore_state_from_tb(cpu, tb, retaddr);
373 if (tb->cflags & CF_NOCACHE) {
374
375 tb_phys_invalidate(tb, -1);
376 tb_free(tb);
377 }
378 r = true;
379 }
380 tb_unlock();
381
382 return r;
383}
384
385void page_size_init(void)
386{
387
388
389 qemu_real_host_page_size = getpagesize();
390 qemu_real_host_page_mask = -(intptr_t)qemu_real_host_page_size;
391 if (qemu_host_page_size == 0) {
392 qemu_host_page_size = qemu_real_host_page_size;
393 }
394 if (qemu_host_page_size < TARGET_PAGE_SIZE) {
395 qemu_host_page_size = TARGET_PAGE_SIZE;
396 }
397 qemu_host_page_mask = -(intptr_t)qemu_host_page_size;
398}
399
400static void page_init(void)
401{
402 page_size_init();
403 page_table_config_init();
404
405#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
406 {
407#ifdef HAVE_KINFO_GETVMMAP
408 struct kinfo_vmentry *freep;
409 int i, cnt;
410
411 freep = kinfo_getvmmap(getpid(), &cnt);
412 if (freep) {
413 mmap_lock();
414 for (i = 0; i < cnt; i++) {
415 unsigned long startaddr, endaddr;
416
417 startaddr = freep[i].kve_start;
418 endaddr = freep[i].kve_end;
419 if (h2g_valid(startaddr)) {
420 startaddr = h2g(startaddr) & TARGET_PAGE_MASK;
421
422 if (h2g_valid(endaddr)) {
423 endaddr = h2g(endaddr);
424 page_set_flags(startaddr, endaddr, PAGE_RESERVED);
425 } else {
426#if TARGET_ABI_BITS <= L1_MAP_ADDR_SPACE_BITS
427 endaddr = ~0ul;
428 page_set_flags(startaddr, endaddr, PAGE_RESERVED);
429#endif
430 }
431 }
432 }
433 free(freep);
434 mmap_unlock();
435 }
436#else
437 FILE *f;
438
439 last_brk = (unsigned long)sbrk(0);
440
441 f = fopen("/compat/linux/proc/self/maps", "r");
442 if (f) {
443 mmap_lock();
444
445 do {
446 unsigned long startaddr, endaddr;
447 int n;
448
449 n = fscanf(f, "%lx-%lx %*[^\n]\n", &startaddr, &endaddr);
450
451 if (n == 2 && h2g_valid(startaddr)) {
452 startaddr = h2g(startaddr) & TARGET_PAGE_MASK;
453
454 if (h2g_valid(endaddr)) {
455 endaddr = h2g(endaddr);
456 } else {
457 endaddr = ~0ul;
458 }
459 page_set_flags(startaddr, endaddr, PAGE_RESERVED);
460 }
461 } while (!feof(f));
462
463 fclose(f);
464 mmap_unlock();
465 }
466#endif
467 }
468#endif
469}
470
471
472
473
474
475static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
476{
477 PageDesc *pd;
478 void **lp;
479 int i;
480
481 if (alloc) {
482 assert_memory_lock();
483 }
484
485
486 lp = l1_map + ((index >> v_l1_shift) & (v_l1_size - 1));
487
488
489 for (i = v_l2_levels; i > 0; i--) {
490 void **p = atomic_rcu_read(lp);
491
492 if (p == NULL) {
493 if (!alloc) {
494 return NULL;
495 }
496 p = g_new0(void *, V_L2_SIZE);
497 atomic_rcu_set(lp, p);
498 }
499
500 lp = p + ((index >> (i * V_L2_BITS)) & (V_L2_SIZE - 1));
501 }
502
503 pd = atomic_rcu_read(lp);
504 if (pd == NULL) {
505 if (!alloc) {
506 return NULL;
507 }
508 pd = g_new0(PageDesc, V_L2_SIZE);
509 atomic_rcu_set(lp, pd);
510 }
511
512 return pd + (index & (V_L2_SIZE - 1));
513}
514
515static inline PageDesc *page_find(tb_page_addr_t index)
516{
517 return page_find_alloc(index, 0);
518}
519
520#if defined(CONFIG_USER_ONLY)
521
522
523
524
525#define USE_STATIC_CODE_GEN_BUFFER
526#endif
527
528
529
530#define MIN_CODE_GEN_BUFFER_SIZE (1024u * 1024)
531
532
533
534
535#if defined(__x86_64__)
536# define MAX_CODE_GEN_BUFFER_SIZE (2ul * 1024 * 1024 * 1024)
537#elif defined(__sparc__)
538# define MAX_CODE_GEN_BUFFER_SIZE (2ul * 1024 * 1024 * 1024)
539#elif defined(__powerpc64__)
540# define MAX_CODE_GEN_BUFFER_SIZE (2ul * 1024 * 1024 * 1024)
541#elif defined(__powerpc__)
542# define MAX_CODE_GEN_BUFFER_SIZE (32u * 1024 * 1024)
543#elif defined(__aarch64__)
544# define MAX_CODE_GEN_BUFFER_SIZE (128ul * 1024 * 1024)
545#elif defined(__arm__)
546# define MAX_CODE_GEN_BUFFER_SIZE (16u * 1024 * 1024)
547#elif defined(__s390x__)
548
549# define MAX_CODE_GEN_BUFFER_SIZE (3ul * 1024 * 1024 * 1024)
550#elif defined(__mips__)
551
552
553# define MAX_CODE_GEN_BUFFER_SIZE (128ul * 1024 * 1024)
554#else
555# define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
556#endif
557
558#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (32u * 1024 * 1024)
559
560#define DEFAULT_CODE_GEN_BUFFER_SIZE \
561 (DEFAULT_CODE_GEN_BUFFER_SIZE_1 < MAX_CODE_GEN_BUFFER_SIZE \
562 ? DEFAULT_CODE_GEN_BUFFER_SIZE_1 : MAX_CODE_GEN_BUFFER_SIZE)
563
564static inline size_t size_code_gen_buffer(size_t tb_size)
565{
566
567 if (tb_size == 0) {
568#ifdef USE_STATIC_CODE_GEN_BUFFER
569 tb_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
570#else
571
572
573
574
575 tb_size = (unsigned long)(ram_size / 4);
576#endif
577 }
578 if (tb_size < MIN_CODE_GEN_BUFFER_SIZE) {
579 tb_size = MIN_CODE_GEN_BUFFER_SIZE;
580 }
581 if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) {
582 tb_size = MAX_CODE_GEN_BUFFER_SIZE;
583 }
584 return tb_size;
585}
586
587#ifdef __mips__
588
589
590static inline bool cross_256mb(void *addr, size_t size)
591{
592 return ((uintptr_t)addr ^ ((uintptr_t)addr + size)) & ~0x0ffffffful;
593}
594
595
596
597
598static inline void *split_cross_256mb(void *buf1, size_t size1)
599{
600 void *buf2 = (void *)(((uintptr_t)buf1 + size1) & ~0x0ffffffful);
601 size_t size2 = buf1 + size1 - buf2;
602
603 size1 = buf2 - buf1;
604 if (size1 < size2) {
605 size1 = size2;
606 buf1 = buf2;
607 }
608
609 tcg_ctx.code_gen_buffer_size = size1;
610 return buf1;
611}
612#endif
613
614#ifdef USE_STATIC_CODE_GEN_BUFFER
615static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
616 __attribute__((aligned(CODE_GEN_ALIGN)));
617
618# ifdef _WIN32
619static inline void do_protect(void *addr, long size, int prot)
620{
621 DWORD old_protect;
622 VirtualProtect(addr, size, prot, &old_protect);
623}
624
625static inline void map_exec(void *addr, long size)
626{
627 do_protect(addr, size, PAGE_EXECUTE_READWRITE);
628}
629
630static inline void map_none(void *addr, long size)
631{
632 do_protect(addr, size, PAGE_NOACCESS);
633}
634# else
635static inline void do_protect(void *addr, long size, int prot)
636{
637 uintptr_t start, end;
638
639 start = (uintptr_t)addr;
640 start &= qemu_real_host_page_mask;
641
642 end = (uintptr_t)addr + size;
643 end = ROUND_UP(end, qemu_real_host_page_size);
644
645 mprotect((void *)start, end - start, prot);
646}
647
648static inline void map_exec(void *addr, long size)
649{
650 do_protect(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC);
651}
652
653static inline void map_none(void *addr, long size)
654{
655 do_protect(addr, size, PROT_NONE);
656}
657# endif
658
659static inline void *alloc_code_gen_buffer(void)
660{
661 void *buf = static_code_gen_buffer;
662 size_t full_size, size;
663
664
665 full_size = (((uintptr_t)buf + sizeof(static_code_gen_buffer))
666 & qemu_real_host_page_mask) - (uintptr_t)buf;
667
668
669 size = full_size - qemu_real_host_page_size;
670
671
672 if (size > tcg_ctx.code_gen_buffer_size) {
673 size = (((uintptr_t)buf + tcg_ctx.code_gen_buffer_size)
674 & qemu_real_host_page_mask) - (uintptr_t)buf;
675 }
676 tcg_ctx.code_gen_buffer_size = size;
677
678#ifdef __mips__
679 if (cross_256mb(buf, size)) {
680 buf = split_cross_256mb(buf, size);
681 size = tcg_ctx.code_gen_buffer_size;
682 }
683#endif
684
685 map_exec(buf, size);
686 map_none(buf + size, qemu_real_host_page_size);
687 qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
688
689 return buf;
690}
691#elif defined(_WIN32)
692static inline void *alloc_code_gen_buffer(void)
693{
694 size_t size = tcg_ctx.code_gen_buffer_size;
695 void *buf1, *buf2;
696
697
698
699 buf1 = VirtualAlloc(NULL, size + qemu_real_host_page_size,
700 MEM_RESERVE, PAGE_NOACCESS);
701 if (buf1 != NULL) {
702 buf2 = VirtualAlloc(buf1, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
703 assert(buf1 == buf2);
704 }
705
706 return buf1;
707}
708#else
709static inline void *alloc_code_gen_buffer(void)
710{
711 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
712 uintptr_t start = 0;
713 size_t size = tcg_ctx.code_gen_buffer_size;
714 void *buf;
715
716
717
718
719# if defined(__PIE__) || defined(__PIC__)
720
721
722
723
724# elif defined(__x86_64__) && defined(MAP_32BIT)
725
726
727 flags |= MAP_32BIT;
728
729 if (size > 800u * 1024 * 1024) {
730 tcg_ctx.code_gen_buffer_size = size = 800u * 1024 * 1024;
731 }
732# elif defined(__sparc__)
733 start = 0x40000000ul;
734# elif defined(__s390x__)
735 start = 0x90000000ul;
736# elif defined(__mips__)
737# if _MIPS_SIM == _ABI64
738 start = 0x128000000ul;
739# else
740 start = 0x08000000ul;
741# endif
742# endif
743
744 buf = mmap((void *)start, size + qemu_real_host_page_size,
745 PROT_NONE, flags, -1, 0);
746 if (buf == MAP_FAILED) {
747 return NULL;
748 }
749
750#ifdef __mips__
751 if (cross_256mb(buf, size)) {
752
753
754 size_t size2;
755 void *buf2 = mmap(NULL, size + qemu_real_host_page_size,
756 PROT_NONE, flags, -1, 0);
757 switch (buf2 != MAP_FAILED) {
758 case 1:
759 if (!cross_256mb(buf2, size)) {
760
761 munmap(buf, size + qemu_real_host_page_size);
762 break;
763 }
764
765 munmap(buf2, size + qemu_real_host_page_size);
766
767 default:
768
769 buf2 = split_cross_256mb(buf, size);
770 size2 = tcg_ctx.code_gen_buffer_size;
771 if (buf == buf2) {
772 munmap(buf + size2 + qemu_real_host_page_size, size - size2);
773 } else {
774 munmap(buf, size - size2);
775 }
776 size = size2;
777 break;
778 }
779 buf = buf2;
780 }
781#endif
782
783
784
785 mprotect(buf, size, PROT_WRITE | PROT_READ | PROT_EXEC);
786
787
788 qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
789
790 return buf;
791}
792#endif
793
794static inline void code_gen_alloc(size_t tb_size)
795{
796 tcg_ctx.code_gen_buffer_size = size_code_gen_buffer(tb_size);
797 tcg_ctx.code_gen_buffer = alloc_code_gen_buffer();
798 if (tcg_ctx.code_gen_buffer == NULL) {
799 fprintf(stderr, "Could not allocate dynamic translator buffer\n");
800 exit(1);
801 }
802
803
804
805
806 tcg_ctx.code_gen_max_blocks
807 = tcg_ctx.code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
808 tcg_ctx.tb_ctx.tbs = g_new(TranslationBlock, tcg_ctx.code_gen_max_blocks);
809
810 qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock);
811}
812
813static void tb_htable_init(void)
814{
815 unsigned int mode = QHT_MODE_AUTO_RESIZE;
816
817 qht_init(&tcg_ctx.tb_ctx.htable, CODE_GEN_HTABLE_SIZE, mode);
818}
819
820
821
822
823void tcg_exec_init(unsigned long tb_size)
824{
825 cpu_gen_init();
826 page_init();
827 tb_htable_init();
828 code_gen_alloc(tb_size);
829#if defined(CONFIG_SOFTMMU)
830
831
832 tcg_prologue_init(&tcg_ctx);
833#endif
834}
835
836bool tcg_enabled(void)
837{
838 return tcg_ctx.code_gen_buffer != NULL;
839}
840
841
842
843
844
845
846
847static TranslationBlock *tb_alloc(target_ulong pc)
848{
849 TranslationBlock *tb;
850
851 assert_tb_lock();
852
853 if (tcg_ctx.tb_ctx.nb_tbs >= tcg_ctx.code_gen_max_blocks) {
854 return NULL;
855 }
856 tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
857 tb->pc = pc;
858 tb->cflags = 0;
859 tb->invalid = false;
860 return tb;
861}
862
863
864void tb_free(TranslationBlock *tb)
865{
866 assert_tb_lock();
867
868
869
870
871 if (tcg_ctx.tb_ctx.nb_tbs > 0 &&
872 tb == &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs - 1]) {
873 tcg_ctx.code_gen_ptr = tb->tc_ptr;
874 tcg_ctx.tb_ctx.nb_tbs--;
875 }
876}
877
878static inline void invalidate_page_bitmap(PageDesc *p)
879{
880#ifdef CONFIG_SOFTMMU
881 g_free(p->code_bitmap);
882 p->code_bitmap = NULL;
883 p->code_write_count = 0;
884#endif
885}
886
887
888static void page_flush_tb_1(int level, void **lp)
889{
890 int i;
891
892 if (*lp == NULL) {
893 return;
894 }
895 if (level == 0) {
896 PageDesc *pd = *lp;
897
898 for (i = 0; i < V_L2_SIZE; ++i) {
899 pd[i].first_tb = NULL;
900 invalidate_page_bitmap(pd + i);
901 }
902 } else {
903 void **pp = *lp;
904
905 for (i = 0; i < V_L2_SIZE; ++i) {
906 page_flush_tb_1(level - 1, pp + i);
907 }
908 }
909}
910
911static void page_flush_tb(void)
912{
913 int i, l1_sz = v_l1_size;
914
915 for (i = 0; i < l1_sz; i++) {
916 page_flush_tb_1(v_l2_levels, l1_map + i);
917 }
918}
919
920
921static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
922{
923 tb_lock();
924
925
926
927
928 if (tcg_ctx.tb_ctx.tb_flush_count != tb_flush_count.host_int) {
929 goto done;
930 }
931
932#if defined(DEBUG_TB_FLUSH)
933 printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
934 (unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer),
935 tcg_ctx.tb_ctx.nb_tbs, tcg_ctx.tb_ctx.nb_tbs > 0 ?
936 ((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)) /
937 tcg_ctx.tb_ctx.nb_tbs : 0);
938#endif
939 if ((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)
940 > tcg_ctx.code_gen_buffer_size) {
941 cpu_abort(cpu, "Internal error: code buffer overflow\n");
942 }
943
944 CPU_FOREACH(cpu) {
945 int i;
946
947 for (i = 0; i < TB_JMP_CACHE_SIZE; ++i) {
948 atomic_set(&cpu->tb_jmp_cache[i], NULL);
949 }
950 }
951
952 tcg_ctx.tb_ctx.nb_tbs = 0;
953 qht_reset_size(&tcg_ctx.tb_ctx.htable, CODE_GEN_HTABLE_SIZE);
954 page_flush_tb();
955
956 tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
957
958
959 atomic_mb_set(&tcg_ctx.tb_ctx.tb_flush_count,
960 tcg_ctx.tb_ctx.tb_flush_count + 1);
961
962done:
963 tb_unlock();
964}
965
966void tb_flush(CPUState *cpu)
967{
968 if (tcg_enabled()) {
969 unsigned tb_flush_count = atomic_mb_read(&tcg_ctx.tb_ctx.tb_flush_count);
970 async_safe_run_on_cpu(cpu, do_tb_flush,
971 RUN_ON_CPU_HOST_INT(tb_flush_count));
972 }
973}
974
975#ifdef DEBUG_TB_CHECK
976
977static void
978do_tb_invalidate_check(struct qht *ht, void *p, uint32_t hash, void *userp)
979{
980 TranslationBlock *tb = p;
981 target_ulong addr = *(target_ulong *)userp;
982
983 if (!(addr + TARGET_PAGE_SIZE <= tb->pc || addr >= tb->pc + tb->size)) {
984 printf("ERROR invalidate: address=" TARGET_FMT_lx
985 " PC=%08lx size=%04x\n", addr, (long)tb->pc, tb->size);
986 }
987}
988
989
990
991
992
993static void tb_invalidate_check(target_ulong address)
994{
995 address &= TARGET_PAGE_MASK;
996 qht_iter(&tcg_ctx.tb_ctx.htable, do_tb_invalidate_check, &address);
997}
998
999static void
1000do_tb_page_check(struct qht *ht, void *p, uint32_t hash, void *userp)
1001{
1002 TranslationBlock *tb = p;
1003 int flags1, flags2;
1004
1005 flags1 = page_get_flags(tb->pc);
1006 flags2 = page_get_flags(tb->pc + tb->size - 1);
1007 if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
1008 printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
1009 (long)tb->pc, tb->size, flags1, flags2);
1010 }
1011}
1012
1013
1014static void tb_page_check(void)
1015{
1016 qht_iter(&tcg_ctx.tb_ctx.htable, do_tb_page_check, NULL);
1017}
1018
1019#endif
1020
1021static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
1022{
1023 TranslationBlock *tb1;
1024 unsigned int n1;
1025
1026 for (;;) {
1027 tb1 = *ptb;
1028 n1 = (uintptr_t)tb1 & 3;
1029 tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
1030 if (tb1 == tb) {
1031 *ptb = tb1->page_next[n1];
1032 break;
1033 }
1034 ptb = &tb1->page_next[n1];
1035 }
1036}
1037
1038
1039static inline void tb_remove_from_jmp_list(TranslationBlock *tb, int n)
1040{
1041 TranslationBlock *tb1;
1042 uintptr_t *ptb, ntb;
1043 unsigned int n1;
1044
1045 ptb = &tb->jmp_list_next[n];
1046 if (*ptb) {
1047
1048 for (;;) {
1049 ntb = *ptb;
1050 n1 = ntb & 3;
1051 tb1 = (TranslationBlock *)(ntb & ~3);
1052 if (n1 == n && tb1 == tb) {
1053 break;
1054 }
1055 if (n1 == 2) {
1056 ptb = &tb1->jmp_list_first;
1057 } else {
1058 ptb = &tb1->jmp_list_next[n1];
1059 }
1060 }
1061
1062 *ptb = tb->jmp_list_next[n];
1063
1064 tb->jmp_list_next[n] = (uintptr_t)NULL;
1065 }
1066}
1067
1068
1069
1070static inline void tb_reset_jump(TranslationBlock *tb, int n)
1071{
1072 uintptr_t addr = (uintptr_t)(tb->tc_ptr + tb->jmp_reset_offset[n]);
1073 tb_set_jmp_target(tb, n, addr);
1074}
1075
1076
1077static inline void tb_jmp_unlink(TranslationBlock *tb)
1078{
1079 TranslationBlock *tb1;
1080 uintptr_t *ptb, ntb;
1081 unsigned int n1;
1082
1083 ptb = &tb->jmp_list_first;
1084 for (;;) {
1085 ntb = *ptb;
1086 n1 = ntb & 3;
1087 tb1 = (TranslationBlock *)(ntb & ~3);
1088 if (n1 == 2) {
1089 break;
1090 }
1091 tb_reset_jump(tb1, n1);
1092 *ptb = tb1->jmp_list_next[n1];
1093 tb1->jmp_list_next[n1] = (uintptr_t)NULL;
1094 }
1095}
1096
1097
1098
1099
1100
1101void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
1102{
1103 CPUState *cpu;
1104 PageDesc *p;
1105 uint32_t h;
1106 tb_page_addr_t phys_pc;
1107
1108 assert_tb_lock();
1109
1110 atomic_set(&tb->invalid, true);
1111
1112
1113 phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
1114 h = tb_hash_func(phys_pc, tb->pc, tb->flags);
1115 qht_remove(&tcg_ctx.tb_ctx.htable, tb, h);
1116
1117
1118 if (tb->page_addr[0] != page_addr) {
1119 p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
1120 tb_page_remove(&p->first_tb, tb);
1121 invalidate_page_bitmap(p);
1122 }
1123 if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
1124 p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
1125 tb_page_remove(&p->first_tb, tb);
1126 invalidate_page_bitmap(p);
1127 }
1128
1129
1130 h = tb_jmp_cache_hash_func(tb->pc);
1131 CPU_FOREACH(cpu) {
1132 if (atomic_read(&cpu->tb_jmp_cache[h]) == tb) {
1133 atomic_set(&cpu->tb_jmp_cache[h], NULL);
1134 }
1135 }
1136
1137
1138 tb_remove_from_jmp_list(tb, 0);
1139 tb_remove_from_jmp_list(tb, 1);
1140
1141
1142 tb_jmp_unlink(tb);
1143
1144 tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
1145}
1146
1147#ifdef CONFIG_SOFTMMU
1148static void build_page_bitmap(PageDesc *p)
1149{
1150 int n, tb_start, tb_end;
1151 TranslationBlock *tb;
1152
1153 p->code_bitmap = bitmap_new(TARGET_PAGE_SIZE);
1154
1155 tb = p->first_tb;
1156 while (tb != NULL) {
1157 n = (uintptr_t)tb & 3;
1158 tb = (TranslationBlock *)((uintptr_t)tb & ~3);
1159
1160 if (n == 0) {
1161
1162
1163 tb_start = tb->pc & ~TARGET_PAGE_MASK;
1164 tb_end = tb_start + tb->size;
1165 if (tb_end > TARGET_PAGE_SIZE) {
1166 tb_end = TARGET_PAGE_SIZE;
1167 }
1168 } else {
1169 tb_start = 0;
1170 tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
1171 }
1172 bitmap_set(p->code_bitmap, tb_start, tb_end - tb_start);
1173 tb = tb->page_next[n];
1174 }
1175}
1176#endif
1177
1178
1179
1180
1181
1182static inline void tb_alloc_page(TranslationBlock *tb,
1183 unsigned int n, tb_page_addr_t page_addr)
1184{
1185 PageDesc *p;
1186#ifndef CONFIG_USER_ONLY
1187 bool page_already_protected;
1188#endif
1189
1190 assert_memory_lock();
1191
1192 tb->page_addr[n] = page_addr;
1193 p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1);
1194 tb->page_next[n] = p->first_tb;
1195#ifndef CONFIG_USER_ONLY
1196 page_already_protected = p->first_tb != NULL;
1197#endif
1198 p->first_tb = (TranslationBlock *)((uintptr_t)tb | n);
1199 invalidate_page_bitmap(p);
1200
1201#if defined(CONFIG_USER_ONLY)
1202 if (p->flags & PAGE_WRITE) {
1203 target_ulong addr;
1204 PageDesc *p2;
1205 int prot;
1206
1207
1208
1209 page_addr &= qemu_host_page_mask;
1210 prot = 0;
1211 for (addr = page_addr; addr < page_addr + qemu_host_page_size;
1212 addr += TARGET_PAGE_SIZE) {
1213
1214 p2 = page_find(addr >> TARGET_PAGE_BITS);
1215 if (!p2) {
1216 continue;
1217 }
1218 prot |= p2->flags;
1219 p2->flags &= ~PAGE_WRITE;
1220 }
1221 mprotect(g2h(page_addr), qemu_host_page_size,
1222 (prot & PAGE_BITS) & ~PAGE_WRITE);
1223#ifdef DEBUG_TB_INVALIDATE
1224 printf("protecting code page: 0x" TARGET_FMT_lx "\n",
1225 page_addr);
1226#endif
1227 }
1228#else
1229
1230
1231
1232 if (!page_already_protected) {
1233 tlb_protect_code(page_addr);
1234 }
1235#endif
1236}
1237
1238
1239
1240
1241
1242
1243static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
1244 tb_page_addr_t phys_page2)
1245{
1246 uint32_t h;
1247
1248 assert_memory_lock();
1249
1250
1251 tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
1252 if (phys_page2 != -1) {
1253 tb_alloc_page(tb, 1, phys_page2);
1254 } else {
1255 tb->page_addr[1] = -1;
1256 }
1257
1258
1259 h = tb_hash_func(phys_pc, tb->pc, tb->flags);
1260 qht_insert(&tcg_ctx.tb_ctx.htable, tb, h);
1261
1262#ifdef DEBUG_TB_CHECK
1263 tb_page_check();
1264#endif
1265}
1266
1267
1268TranslationBlock *tb_gen_code(CPUState *cpu,
1269 target_ulong pc, target_ulong cs_base,
1270 uint32_t flags, int cflags)
1271{
1272 CPUArchState *env = cpu->env_ptr;
1273 TranslationBlock *tb;
1274 tb_page_addr_t phys_pc, phys_page2;
1275 target_ulong virt_page2;
1276 tcg_insn_unit *gen_code_buf;
1277 int gen_code_size, search_size;
1278#ifdef CONFIG_PROFILER
1279 int64_t ti;
1280#endif
1281 assert_memory_lock();
1282
1283 phys_pc = get_page_addr_code(env, pc);
1284 if (use_icount && !(cflags & CF_IGNORE_ICOUNT)) {
1285 cflags |= CF_USE_ICOUNT;
1286 }
1287
1288 tb = tb_alloc(pc);
1289 if (unlikely(!tb)) {
1290 buffer_overflow:
1291
1292 tb_flush(cpu);
1293 mmap_unlock();
1294 cpu_loop_exit(cpu);
1295 }
1296
1297 gen_code_buf = tcg_ctx.code_gen_ptr;
1298 tb->tc_ptr = gen_code_buf;
1299 tb->cs_base = cs_base;
1300 tb->flags = flags;
1301 tb->cflags = cflags;
1302
1303#ifdef CONFIG_PROFILER
1304 tcg_ctx.tb_count1++;
1305
1306 ti = profile_getclock();
1307#endif
1308
1309 tcg_func_start(&tcg_ctx);
1310
1311 tcg_ctx.cpu = ENV_GET_CPU(env);
1312 gen_intermediate_code(env, tb);
1313 tcg_ctx.cpu = NULL;
1314
1315 trace_translate_block(tb, tb->pc, tb->tc_ptr);
1316
1317
1318 tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID;
1319 tb->jmp_reset_offset[1] = TB_JMP_RESET_OFFSET_INVALID;
1320 tcg_ctx.tb_jmp_reset_offset = tb->jmp_reset_offset;
1321#ifdef USE_DIRECT_JUMP
1322 tcg_ctx.tb_jmp_insn_offset = tb->jmp_insn_offset;
1323 tcg_ctx.tb_jmp_target_addr = NULL;
1324#else
1325 tcg_ctx.tb_jmp_insn_offset = NULL;
1326 tcg_ctx.tb_jmp_target_addr = tb->jmp_target_addr;
1327#endif
1328
1329#ifdef CONFIG_PROFILER
1330 tcg_ctx.tb_count++;
1331 tcg_ctx.interm_time += profile_getclock() - ti;
1332 tcg_ctx.code_time -= profile_getclock();
1333#endif
1334
1335
1336
1337
1338
1339
1340 gen_code_size = tcg_gen_code(&tcg_ctx, tb);
1341 if (unlikely(gen_code_size < 0)) {
1342 goto buffer_overflow;
1343 }
1344 search_size = encode_search(tb, (void *)gen_code_buf + gen_code_size);
1345 if (unlikely(search_size < 0)) {
1346 goto buffer_overflow;
1347 }
1348
1349#ifdef CONFIG_PROFILER
1350 tcg_ctx.code_time += profile_getclock();
1351 tcg_ctx.code_in_len += tb->size;
1352 tcg_ctx.code_out_len += gen_code_size;
1353 tcg_ctx.search_out_len += search_size;
1354#endif
1355
1356#ifdef DEBUG_DISAS
1357 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
1358 qemu_log_in_addr_range(tb->pc)) {
1359 qemu_log_lock();
1360 qemu_log("OUT: [size=%d]\n", gen_code_size);
1361 log_disas(tb->tc_ptr, gen_code_size);
1362 qemu_log("\n");
1363 qemu_log_flush();
1364 qemu_log_unlock();
1365 }
1366#endif
1367
1368 tcg_ctx.code_gen_ptr = (void *)
1369 ROUND_UP((uintptr_t)gen_code_buf + gen_code_size + search_size,
1370 CODE_GEN_ALIGN);
1371
1372
1373 assert(((uintptr_t)tb & 3) == 0);
1374 tb->jmp_list_first = (uintptr_t)tb | 2;
1375 tb->jmp_list_next[0] = (uintptr_t)NULL;
1376 tb->jmp_list_next[1] = (uintptr_t)NULL;
1377
1378
1379 if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
1380 tb_reset_jump(tb, 0);
1381 }
1382 if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) {
1383 tb_reset_jump(tb, 1);
1384 }
1385
1386
1387 virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
1388 phys_page2 = -1;
1389 if ((pc & TARGET_PAGE_MASK) != virt_page2) {
1390 phys_page2 = get_page_addr_code(env, virt_page2);
1391 }
1392
1393
1394
1395
1396
1397 tb_link_page(tb, phys_pc, phys_page2);
1398
1399 if (qemu_etrace_mask(ETRACE_F_TRANSLATION)) {
1400 CPUState *cpu = ENV_GET_CPU(env);
1401 hwaddr phys_addr = pc;
1402
1403#if !defined(CONFIG_USER_ONLY)
1404 phys_addr = cpu_get_phys_page_debug(cpu, pc & TARGET_PAGE_MASK);
1405 phys_addr += pc & ~TARGET_PAGE_MASK;
1406#endif
1407 etrace_dump_tb(&qemu_etracer, NULL, cpu->cpu_index,
1408 tb->pc, phys_addr, tb->size,
1409 tb->tc_ptr, gen_code_size);
1410 }
1411
1412 return tb;
1413}
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425static void tb_invalidate_phys_range_1(tb_page_addr_t start, tb_page_addr_t end)
1426{
1427 while (start < end) {
1428 tb_invalidate_phys_page_range(start, end, 0);
1429 start &= TARGET_PAGE_MASK;
1430 start += TARGET_PAGE_SIZE;
1431 }
1432}
1433
1434#ifdef CONFIG_SOFTMMU
1435void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end)
1436{
1437 assert_tb_lock();
1438 tb_invalidate_phys_range_1(start, end);
1439}
1440#else
1441void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end)
1442{
1443 assert_memory_lock();
1444 tb_lock();
1445 tb_invalidate_phys_range_1(start, end);
1446 tb_unlock();
1447}
1448#endif
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
1460 int is_cpu_write_access)
1461{
1462 TranslationBlock *tb, *tb_next;
1463#if defined(TARGET_HAS_PRECISE_SMC)
1464 CPUState *cpu = current_cpu;
1465 CPUArchState *env = NULL;
1466#endif
1467 tb_page_addr_t tb_start, tb_end;
1468 PageDesc *p;
1469 int n;
1470#ifdef TARGET_HAS_PRECISE_SMC
1471 int current_tb_not_found = is_cpu_write_access;
1472 TranslationBlock *current_tb = NULL;
1473 int current_tb_modified = 0;
1474 target_ulong current_pc = 0;
1475 target_ulong current_cs_base = 0;
1476 uint32_t current_flags = 0;
1477#endif
1478
1479 assert_memory_lock();
1480 assert_tb_lock();
1481
1482 p = page_find(start >> TARGET_PAGE_BITS);
1483 if (!p) {
1484 return;
1485 }
1486#if defined(TARGET_HAS_PRECISE_SMC)
1487 if (cpu != NULL) {
1488 env = cpu->env_ptr;
1489 }
1490#endif
1491
1492
1493
1494
1495 tb = p->first_tb;
1496 while (tb != NULL) {
1497 n = (uintptr_t)tb & 3;
1498 tb = (TranslationBlock *)((uintptr_t)tb & ~3);
1499 tb_next = tb->page_next[n];
1500
1501 if (n == 0) {
1502
1503
1504 tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
1505 tb_end = tb_start + tb->size;
1506 } else {
1507 tb_start = tb->page_addr[1];
1508 tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
1509 }
1510 if (!(tb_end <= start || tb_start >= end)) {
1511#ifdef TARGET_HAS_PRECISE_SMC
1512 if (current_tb_not_found) {
1513 current_tb_not_found = 0;
1514 current_tb = NULL;
1515 if (cpu->mem_io_pc) {
1516
1517 current_tb = tb_find_pc(cpu->mem_io_pc);
1518 }
1519 }
1520 if (current_tb == tb &&
1521 (current_tb->cflags & CF_COUNT_MASK) != 1) {
1522
1523
1524
1525
1526
1527
1528 current_tb_modified = 1;
1529 cpu_restore_state_from_tb(cpu, current_tb, cpu->mem_io_pc);
1530 cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
1531 ¤t_flags);
1532 }
1533#endif
1534 tb_phys_invalidate(tb, -1);
1535 }
1536 tb = tb_next;
1537 }
1538#if !defined(CONFIG_USER_ONLY)
1539
1540 if (!p->first_tb) {
1541 invalidate_page_bitmap(p);
1542 tlb_unprotect_code(start);
1543 }
1544#endif
1545#ifdef TARGET_HAS_PRECISE_SMC
1546 if (current_tb_modified) {
1547
1548
1549
1550 tb_gen_code(cpu, current_pc, current_cs_base, current_flags, 1);
1551 cpu_loop_exit_noexc(cpu);
1552 }
1553#endif
1554}
1555
1556#ifdef CONFIG_SOFTMMU
1557
1558
1559
1560
1561void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
1562{
1563 PageDesc *p;
1564
1565#if 0
1566 if (1) {
1567 qemu_log("modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
1568 cpu_single_env->mem_io_vaddr, len,
1569 cpu_single_env->eip,
1570 cpu_single_env->eip +
1571 (intptr_t)cpu_single_env->segs[R_CS].base);
1572 }
1573#endif
1574 assert_memory_lock();
1575
1576 p = page_find(start >> TARGET_PAGE_BITS);
1577 if (!p) {
1578 return;
1579 }
1580 if (!p->code_bitmap &&
1581 ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD) {
1582
1583
1584
1585 build_page_bitmap(p);
1586 }
1587 if (p->code_bitmap) {
1588 unsigned int nr;
1589 unsigned long b;
1590
1591 nr = start & ~TARGET_PAGE_MASK;
1592 b = p->code_bitmap[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG - 1));
1593 if (b & ((1 << len) - 1)) {
1594 goto do_invalidate;
1595 }
1596 } else {
1597 do_invalidate:
1598 tb_invalidate_phys_page_range(start, start + len, 1);
1599 }
1600}
1601#else
1602
1603
1604
1605
1606
1607
1608static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc)
1609{
1610 TranslationBlock *tb;
1611 PageDesc *p;
1612 int n;
1613#ifdef TARGET_HAS_PRECISE_SMC
1614 TranslationBlock *current_tb = NULL;
1615 CPUState *cpu = current_cpu;
1616 CPUArchState *env = NULL;
1617 int current_tb_modified = 0;
1618 target_ulong current_pc = 0;
1619 target_ulong current_cs_base = 0;
1620 uint32_t current_flags = 0;
1621#endif
1622
1623 assert_memory_lock();
1624
1625 addr &= TARGET_PAGE_MASK;
1626 p = page_find(addr >> TARGET_PAGE_BITS);
1627 if (!p) {
1628 return false;
1629 }
1630
1631 tb_lock();
1632 tb = p->first_tb;
1633#ifdef TARGET_HAS_PRECISE_SMC
1634 if (tb && pc != 0) {
1635 current_tb = tb_find_pc(pc);
1636 }
1637 if (cpu != NULL) {
1638 env = cpu->env_ptr;
1639 }
1640#endif
1641 while (tb != NULL) {
1642 n = (uintptr_t)tb & 3;
1643 tb = (TranslationBlock *)((uintptr_t)tb & ~3);
1644#ifdef TARGET_HAS_PRECISE_SMC
1645 if (current_tb == tb &&
1646 (current_tb->cflags & CF_COUNT_MASK) != 1) {
1647
1648
1649
1650
1651
1652
1653 current_tb_modified = 1;
1654 cpu_restore_state_from_tb(cpu, current_tb, pc);
1655 cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
1656 ¤t_flags);
1657 }
1658#endif
1659 tb_phys_invalidate(tb, addr);
1660 tb = tb->page_next[n];
1661 }
1662 p->first_tb = NULL;
1663#ifdef TARGET_HAS_PRECISE_SMC
1664 if (current_tb_modified) {
1665
1666
1667
1668 tb_gen_code(cpu, current_pc, current_cs_base, current_flags, 1);
1669
1670
1671 return true;
1672 }
1673#endif
1674 tb_unlock();
1675
1676 return false;
1677}
1678#endif
1679
1680
1681
1682static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
1683{
1684 int m_min, m_max, m;
1685 uintptr_t v;
1686 TranslationBlock *tb;
1687
1688 if (tcg_ctx.tb_ctx.nb_tbs <= 0) {
1689 return NULL;
1690 }
1691 if (tc_ptr < (uintptr_t)tcg_ctx.code_gen_buffer ||
1692 tc_ptr >= (uintptr_t)tcg_ctx.code_gen_ptr) {
1693 return NULL;
1694 }
1695
1696 m_min = 0;
1697 m_max = tcg_ctx.tb_ctx.nb_tbs - 1;
1698 while (m_min <= m_max) {
1699 m = (m_min + m_max) >> 1;
1700 tb = &tcg_ctx.tb_ctx.tbs[m];
1701 v = (uintptr_t)tb->tc_ptr;
1702 if (v == tc_ptr) {
1703 return tb;
1704 } else if (tc_ptr < v) {
1705 m_max = m - 1;
1706 } else {
1707 m_min = m + 1;
1708 }
1709 }
1710 return &tcg_ctx.tb_ctx.tbs[m_max];
1711}
1712
1713#if !defined(CONFIG_USER_ONLY)
1714void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
1715{
1716 ram_addr_t ram_addr;
1717 MemoryRegion *mr;
1718 hwaddr l = 1;
1719
1720 rcu_read_lock();
1721 mr = address_space_translate(as, addr, &addr, &l, false);
1722 if (!(memory_region_is_ram(mr)
1723 || memory_region_is_romd(mr))) {
1724 rcu_read_unlock();
1725 return;
1726 }
1727 ram_addr = memory_region_get_ram_addr(mr) + addr;
1728 tb_lock();
1729 tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
1730 tb_unlock();
1731 rcu_read_unlock();
1732}
1733#endif
1734
1735
1736void tb_check_watchpoint(CPUState *cpu)
1737{
1738 TranslationBlock *tb;
1739
1740 tb = tb_find_pc(cpu->mem_io_pc);
1741 if (tb) {
1742
1743 cpu_restore_state_from_tb(cpu, tb, cpu->mem_io_pc);
1744 tb_phys_invalidate(tb, -1);
1745 } else {
1746
1747
1748 CPUArchState *env = cpu->env_ptr;
1749 target_ulong pc, cs_base;
1750 tb_page_addr_t addr;
1751 uint32_t flags;
1752
1753 cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
1754 addr = get_page_addr_code(env, pc);
1755 tb_invalidate_phys_range(addr, addr + 1);
1756 }
1757}
1758
1759#ifndef CONFIG_USER_ONLY
1760
1761
1762void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
1763{
1764#if defined(TARGET_MIPS) || defined(TARGET_SH4)
1765 CPUArchState *env = cpu->env_ptr;
1766#endif
1767 TranslationBlock *tb;
1768 uint32_t n, cflags;
1769 target_ulong pc, cs_base;
1770 uint32_t flags;
1771
1772 tb_lock();
1773 tb = tb_find_pc(retaddr);
1774 if (!tb) {
1775 cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p",
1776 (void *)retaddr);
1777 }
1778 n = cpu->icount_decr.u16.low + tb->icount;
1779 cpu_restore_state_from_tb(cpu, tb, retaddr);
1780
1781
1782 n = n - cpu->icount_decr.u16.low;
1783
1784 n++;
1785
1786
1787
1788
1789#if defined(TARGET_MIPS)
1790 if ((env->hflags & MIPS_HFLAG_BMASK) != 0 && n > 1) {
1791 env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
1792 cpu->icount_decr.u16.low++;
1793 env->hflags &= ~MIPS_HFLAG_BMASK;
1794 }
1795#elif defined(TARGET_SH4)
1796 if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0
1797 && n > 1) {
1798 env->pc -= 2;
1799 cpu->icount_decr.u16.low++;
1800 env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1801 }
1802#endif
1803
1804 if (n > CF_COUNT_MASK) {
1805 cpu_abort(cpu, "TB too big during recompile");
1806 }
1807
1808 cflags = n | CF_LAST_IO;
1809 pc = tb->pc;
1810 cs_base = tb->cs_base;
1811 flags = tb->flags;
1812 tb_phys_invalidate(tb, -1);
1813 if (tb->cflags & CF_NOCACHE) {
1814 if (tb->orig_tb) {
1815
1816
1817 tb_phys_invalidate(tb->orig_tb, -1);
1818 }
1819 tb_free(tb);
1820 }
1821
1822
1823 tb_gen_code(cpu, pc, cs_base, flags, cflags);
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834 cpu_loop_exit_noexc(cpu);
1835}
1836
1837void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr)
1838{
1839 unsigned int i;
1840
1841
1842
1843 i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
1844 memset(&cpu->tb_jmp_cache[i], 0,
1845 TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
1846
1847 i = tb_jmp_cache_hash_page(addr);
1848 memset(&cpu->tb_jmp_cache[i], 0,
1849 TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
1850}
1851
1852static void print_qht_statistics(FILE *f, fprintf_function cpu_fprintf,
1853 struct qht_stats hst)
1854{
1855 uint32_t hgram_opts;
1856 size_t hgram_bins;
1857 char *hgram;
1858
1859 if (!hst.head_buckets) {
1860 return;
1861 }
1862 cpu_fprintf(f, "TB hash buckets %zu/%zu (%0.2f%% head buckets used)\n",
1863 hst.used_head_buckets, hst.head_buckets,
1864 (double)hst.used_head_buckets / hst.head_buckets * 100);
1865
1866 hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS;
1867 hgram_opts |= QDIST_PR_100X | QDIST_PR_PERCENT;
1868 if (qdist_xmax(&hst.occupancy) - qdist_xmin(&hst.occupancy) == 1) {
1869 hgram_opts |= QDIST_PR_NODECIMAL;
1870 }
1871 hgram = qdist_pr(&hst.occupancy, 10, hgram_opts);
1872 cpu_fprintf(f, "TB hash occupancy %0.2f%% avg chain occ. Histogram: %s\n",
1873 qdist_avg(&hst.occupancy) * 100, hgram);
1874 g_free(hgram);
1875
1876 hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS;
1877 hgram_bins = qdist_xmax(&hst.chain) - qdist_xmin(&hst.chain);
1878 if (hgram_bins > 10) {
1879 hgram_bins = 10;
1880 } else {
1881 hgram_bins = 0;
1882 hgram_opts |= QDIST_PR_NODECIMAL | QDIST_PR_NOBINRANGE;
1883 }
1884 hgram = qdist_pr(&hst.chain, hgram_bins, hgram_opts);
1885 cpu_fprintf(f, "TB hash avg chain %0.3f buckets. Histogram: %s\n",
1886 qdist_avg(&hst.chain), hgram);
1887 g_free(hgram);
1888}
1889
1890void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
1891{
1892 int i, target_code_size, max_target_code_size;
1893 int direct_jmp_count, direct_jmp2_count, cross_page;
1894 TranslationBlock *tb;
1895 struct qht_stats hst;
1896
1897 tb_lock();
1898
1899 target_code_size = 0;
1900 max_target_code_size = 0;
1901 cross_page = 0;
1902 direct_jmp_count = 0;
1903 direct_jmp2_count = 0;
1904 for (i = 0; i < tcg_ctx.tb_ctx.nb_tbs; i++) {
1905 tb = &tcg_ctx.tb_ctx.tbs[i];
1906 target_code_size += tb->size;
1907 if (tb->size > max_target_code_size) {
1908 max_target_code_size = tb->size;
1909 }
1910 if (tb->page_addr[1] != -1) {
1911 cross_page++;
1912 }
1913 if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
1914 direct_jmp_count++;
1915 if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) {
1916 direct_jmp2_count++;
1917 }
1918 }
1919 }
1920
1921 cpu_fprintf(f, "Translation buffer state:\n");
1922 cpu_fprintf(f, "gen code size %td/%zd\n",
1923 tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer,
1924 tcg_ctx.code_gen_highwater - tcg_ctx.code_gen_buffer);
1925 cpu_fprintf(f, "TB count %d/%d\n",
1926 tcg_ctx.tb_ctx.nb_tbs, tcg_ctx.code_gen_max_blocks);
1927 cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
1928 tcg_ctx.tb_ctx.nb_tbs ? target_code_size /
1929 tcg_ctx.tb_ctx.nb_tbs : 0,
1930 max_target_code_size);
1931 cpu_fprintf(f, "TB avg host size %td bytes (expansion ratio: %0.1f)\n",
1932 tcg_ctx.tb_ctx.nb_tbs ? (tcg_ctx.code_gen_ptr -
1933 tcg_ctx.code_gen_buffer) /
1934 tcg_ctx.tb_ctx.nb_tbs : 0,
1935 target_code_size ? (double) (tcg_ctx.code_gen_ptr -
1936 tcg_ctx.code_gen_buffer) /
1937 target_code_size : 0);
1938 cpu_fprintf(f, "cross page TB count %d (%d%%)\n", cross_page,
1939 tcg_ctx.tb_ctx.nb_tbs ? (cross_page * 100) /
1940 tcg_ctx.tb_ctx.nb_tbs : 0);
1941 cpu_fprintf(f, "direct jump count %d (%d%%) (2 jumps=%d %d%%)\n",
1942 direct_jmp_count,
1943 tcg_ctx.tb_ctx.nb_tbs ? (direct_jmp_count * 100) /
1944 tcg_ctx.tb_ctx.nb_tbs : 0,
1945 direct_jmp2_count,
1946 tcg_ctx.tb_ctx.nb_tbs ? (direct_jmp2_count * 100) /
1947 tcg_ctx.tb_ctx.nb_tbs : 0);
1948
1949 qht_statistics_init(&tcg_ctx.tb_ctx.htable, &hst);
1950 print_qht_statistics(f, cpu_fprintf, hst);
1951 qht_statistics_destroy(&hst);
1952
1953 cpu_fprintf(f, "\nStatistics:\n");
1954 cpu_fprintf(f, "TB flush count %u\n",
1955 atomic_read(&tcg_ctx.tb_ctx.tb_flush_count));
1956 cpu_fprintf(f, "TB invalidate count %d\n",
1957 tcg_ctx.tb_ctx.tb_phys_invalidate_count);
1958 cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count);
1959 tcg_dump_info(f, cpu_fprintf);
1960
1961 tb_unlock();
1962}
1963
1964void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf)
1965{
1966 tcg_dump_op_count(f, cpu_fprintf);
1967}
1968
1969#else
1970
1971void cpu_interrupt(CPUState *cpu, int mask)
1972{
1973 cpu->interrupt_request |= mask;
1974 cpu->tcg_exit_req = 1;
1975}
1976
1977
1978
1979
1980
1981struct walk_memory_regions_data {
1982 walk_memory_regions_fn fn;
1983 void *priv;
1984 target_ulong start;
1985 int prot;
1986};
1987
1988static int walk_memory_regions_end(struct walk_memory_regions_data *data,
1989 target_ulong end, int new_prot)
1990{
1991 if (data->start != -1u) {
1992 int rc = data->fn(data->priv, data->start, end, data->prot);
1993 if (rc != 0) {
1994 return rc;
1995 }
1996 }
1997
1998 data->start = (new_prot ? end : -1u);
1999 data->prot = new_prot;
2000
2001 return 0;
2002}
2003
2004static int walk_memory_regions_1(struct walk_memory_regions_data *data,
2005 target_ulong base, int level, void **lp)
2006{
2007 target_ulong pa;
2008 int i, rc;
2009
2010 if (*lp == NULL) {
2011 return walk_memory_regions_end(data, base, 0);
2012 }
2013
2014 if (level == 0) {
2015 PageDesc *pd = *lp;
2016
2017 for (i = 0; i < V_L2_SIZE; ++i) {
2018 int prot = pd[i].flags;
2019
2020 pa = base | (i << TARGET_PAGE_BITS);
2021 if (prot != data->prot) {
2022 rc = walk_memory_regions_end(data, pa, prot);
2023 if (rc != 0) {
2024 return rc;
2025 }
2026 }
2027 }
2028 } else {
2029 void **pp = *lp;
2030
2031 for (i = 0; i < V_L2_SIZE; ++i) {
2032 pa = base | ((target_ulong)i <<
2033 (TARGET_PAGE_BITS + V_L2_BITS * level));
2034 rc = walk_memory_regions_1(data, pa, level - 1, pp + i);
2035 if (rc != 0) {
2036 return rc;
2037 }
2038 }
2039 }
2040
2041 return 0;
2042}
2043
2044int walk_memory_regions(void *priv, walk_memory_regions_fn fn)
2045{
2046 struct walk_memory_regions_data data;
2047 uintptr_t i, l1_sz = v_l1_size;
2048
2049 data.fn = fn;
2050 data.priv = priv;
2051 data.start = -1u;
2052 data.prot = 0;
2053
2054 for (i = 0; i < l1_sz; i++) {
2055 target_ulong base = i << (v_l1_shift + TARGET_PAGE_BITS);
2056 int rc = walk_memory_regions_1(&data, base, v_l2_levels, l1_map + i);
2057 if (rc != 0) {
2058 return rc;
2059 }
2060 }
2061
2062 return walk_memory_regions_end(&data, 0, 0);
2063}
2064
2065static int dump_region(void *priv, target_ulong start,
2066 target_ulong end, unsigned long prot)
2067{
2068 FILE *f = (FILE *)priv;
2069
2070 (void) fprintf(f, TARGET_FMT_lx"-"TARGET_FMT_lx
2071 " "TARGET_FMT_lx" %c%c%c\n",
2072 start, end, end - start,
2073 ((prot & PAGE_READ) ? 'r' : '-'),
2074 ((prot & PAGE_WRITE) ? 'w' : '-'),
2075 ((prot & PAGE_EXEC) ? 'x' : '-'));
2076
2077 return 0;
2078}
2079
2080
2081void page_dump(FILE *f)
2082{
2083 const int length = sizeof(target_ulong) * 2;
2084 (void) fprintf(f, "%-*s %-*s %-*s %s\n",
2085 length, "start", length, "end", length, "size", "prot");
2086 walk_memory_regions(f, dump_region);
2087}
2088
2089int page_get_flags(target_ulong address)
2090{
2091 PageDesc *p;
2092
2093 p = page_find(address >> TARGET_PAGE_BITS);
2094 if (!p) {
2095 return 0;
2096 }
2097 return p->flags;
2098}
2099
2100
2101
2102
2103void page_set_flags(target_ulong start, target_ulong end, int flags)
2104{
2105 target_ulong addr, len;
2106
2107
2108
2109
2110#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
2111 assert(end < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
2112#endif
2113 assert(start < end);
2114 assert_memory_lock();
2115
2116 start = start & TARGET_PAGE_MASK;
2117 end = TARGET_PAGE_ALIGN(end);
2118
2119 if (flags & PAGE_WRITE) {
2120 flags |= PAGE_WRITE_ORG;
2121 }
2122
2123 for (addr = start, len = end - start;
2124 len != 0;
2125 len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
2126 PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
2127
2128
2129
2130 if (!(p->flags & PAGE_WRITE) &&
2131 (flags & PAGE_WRITE) &&
2132 p->first_tb) {
2133 tb_invalidate_phys_page(addr, 0);
2134 }
2135 p->flags = flags;
2136 }
2137}
2138
2139int page_check_range(target_ulong start, target_ulong len, int flags)
2140{
2141 PageDesc *p;
2142 target_ulong end;
2143 target_ulong addr;
2144
2145
2146
2147
2148#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
2149 assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
2150#endif
2151
2152 if (len == 0) {
2153 return 0;
2154 }
2155 if (start + len - 1 < start) {
2156
2157 return -1;
2158 }
2159
2160
2161 end = TARGET_PAGE_ALIGN(start + len);
2162 start = start & TARGET_PAGE_MASK;
2163
2164 for (addr = start, len = end - start;
2165 len != 0;
2166 len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
2167 p = page_find(addr >> TARGET_PAGE_BITS);
2168 if (!p) {
2169 return -1;
2170 }
2171 if (!(p->flags & PAGE_VALID)) {
2172 return -1;
2173 }
2174
2175 if ((flags & PAGE_READ) && !(p->flags & PAGE_READ)) {
2176 return -1;
2177 }
2178 if (flags & PAGE_WRITE) {
2179 if (!(p->flags & PAGE_WRITE_ORG)) {
2180 return -1;
2181 }
2182
2183
2184 if (!(p->flags & PAGE_WRITE)) {
2185 if (!page_unprotect(addr, 0)) {
2186 return -1;
2187 }
2188 }
2189 }
2190 }
2191 return 0;
2192}
2193
2194
2195
2196
2197
2198
2199
2200int page_unprotect(target_ulong address, uintptr_t pc)
2201{
2202 unsigned int prot;
2203 bool current_tb_invalidated;
2204 PageDesc *p;
2205 target_ulong host_start, host_end, addr;
2206
2207
2208
2209
2210 mmap_lock();
2211
2212 p = page_find(address >> TARGET_PAGE_BITS);
2213 if (!p) {
2214 mmap_unlock();
2215 return 0;
2216 }
2217
2218
2219
2220 if ((p->flags & PAGE_WRITE_ORG) && !(p->flags & PAGE_WRITE)) {
2221 host_start = address & qemu_host_page_mask;
2222 host_end = host_start + qemu_host_page_size;
2223
2224 prot = 0;
2225 current_tb_invalidated = false;
2226 for (addr = host_start ; addr < host_end ; addr += TARGET_PAGE_SIZE) {
2227 p = page_find(addr >> TARGET_PAGE_BITS);
2228 p->flags |= PAGE_WRITE;
2229 prot |= p->flags;
2230
2231
2232
2233 current_tb_invalidated |= tb_invalidate_phys_page(addr, pc);
2234#ifdef DEBUG_TB_CHECK
2235 tb_invalidate_check(addr);
2236#endif
2237 }
2238 mprotect((void *)g2h(host_start), qemu_host_page_size,
2239 prot & PAGE_BITS);
2240
2241 mmap_unlock();
2242
2243 return current_tb_invalidated ? 2 : 1;
2244 }
2245 mmap_unlock();
2246 return 0;
2247}
2248#endif
2249