~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to translate-all.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include "qemu-common.h"
26
26
#define NO_CPU_IO_DEFS
27
27
#include "cpu.h"
28
 
#include "trace.h"
 
28
#include "trace-root.h"
29
29
#include "disas/disas.h"
30
30
#include "exec/exec-all.h"
31
31
#include "tcg.h"
55
55
#include "translate-all.h"
56
56
#include "qemu/bitmap.h"
57
57
#include "qemu/timer.h"
 
58
#include "qemu/main-loop.h"
58
59
#include "exec/log.h"
 
60
#include "sysemu/cpus.h"
59
61
 
60
62
/* #define DEBUG_TB_INVALIDATE */
61
63
/* #define DEBUG_TB_FLUSH */
62
 
/* #define DEBUG_LOCKING */
63
64
/* make various TB consistency checks */
64
65
/* #define DEBUG_TB_CHECK */
65
66
 
74
75
 * access to the memory related structures are protected with the
75
76
 * mmap_lock.
76
77
 */
77
 
#ifdef DEBUG_LOCKING
78
 
#define DEBUG_MEM_LOCKS 1
79
 
#else
80
 
#define DEBUG_MEM_LOCKS 0
81
 
#endif
82
 
 
83
78
#ifdef CONFIG_SOFTMMU
84
 
#define assert_memory_lock() do { /* nothing */ } while (0)
 
79
#define assert_memory_lock() tcg_debug_assert(have_tb_lock)
85
80
#else
86
 
#define assert_memory_lock() do {               \
87
 
        if (DEBUG_MEM_LOCKS) {                  \
88
 
            g_assert(have_mmap_lock());         \
89
 
        }                                       \
90
 
    } while (0)
 
81
#define assert_memory_lock() tcg_debug_assert(have_mmap_lock())
91
82
#endif
92
83
 
93
84
#define SMC_BITMAP_USE_THRESHOLD 10
145
136
bool parallel_cpus;
146
137
 
147
138
/* translation block context */
148
 
#ifdef CONFIG_USER_ONLY
149
139
__thread int have_tb_lock;
150
 
#endif
151
140
 
152
141
static void page_table_config_init(void)
153
142
{
169
158
    assert(v_l2_levels >= 0);
170
159
}
171
160
 
 
161
#define assert_tb_locked() tcg_debug_assert(have_tb_lock)
 
162
#define assert_tb_unlocked() tcg_debug_assert(!have_tb_lock)
 
163
 
172
164
void tb_lock(void)
173
165
{
174
 
#ifdef CONFIG_USER_ONLY
175
 
    assert(!have_tb_lock);
 
166
    assert_tb_unlocked();
176
167
    qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
177
168
    have_tb_lock++;
178
 
#endif
179
169
}
180
170
 
181
171
void tb_unlock(void)
182
172
{
183
 
#ifdef CONFIG_USER_ONLY
184
 
    assert(have_tb_lock);
 
173
    assert_tb_locked();
185
174
    have_tb_lock--;
186
175
    qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
187
 
#endif
188
176
}
189
177
 
190
178
void tb_lock_reset(void)
191
179
{
192
 
#ifdef CONFIG_USER_ONLY
193
180
    if (have_tb_lock) {
194
181
        qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
195
182
        have_tb_lock = 0;
196
183
    }
197
 
#endif
198
184
}
199
185
 
200
 
#ifdef DEBUG_LOCKING
201
 
#define DEBUG_TB_LOCKS 1
202
 
#else
203
 
#define DEBUG_TB_LOCKS 0
204
 
#endif
205
 
 
206
 
#ifdef CONFIG_SOFTMMU
207
 
#define assert_tb_lock() do { /* nothing */ } while (0)
208
 
#else
209
 
#define assert_tb_lock() do {               \
210
 
        if (DEBUG_TB_LOCKS) {               \
211
 
            g_assert(have_tb_lock);         \
212
 
        }                                   \
213
 
    } while (0)
214
 
#endif
215
 
 
216
 
 
217
186
static TranslationBlock *tb_find_pc(uintptr_t tc_ptr);
218
187
 
219
188
void cpu_gen_init(void)
365
334
    TranslationBlock *tb;
366
335
    bool r = false;
367
336
 
 
337
    /* A retaddr of zero is invalid so we really shouldn't have ended
 
338
     * up here. The target code has likely forgotten to check retaddr
 
339
     * != 0 before attempting to restore state. We return early to
 
340
     * avoid blowing up on a recursive tb_lock(). The target must have
 
341
     * previously survived a failed cpu_restore_state because
 
342
     * tb_find_pc(0) would have failed anyway. It still should be
 
343
     * fixed though.
 
344
     */
 
345
 
 
346
    if (!retaddr) {
 
347
        return r;
 
348
    }
 
349
 
368
350
    tb_lock();
369
351
    tb = tb_find_pc(retaddr);
370
352
    if (tb) {
753
735
        size_t size2;
754
736
        void *buf2 = mmap(NULL, size + qemu_real_host_page_size,
755
737
                          PROT_NONE, flags, -1, 0);
756
 
        switch (buf2 != MAP_FAILED) {
 
738
        switch ((int)(buf2 != MAP_FAILED)) {
757
739
        case 1:
758
740
            if (!cross_256mb(buf2, size)) {
759
741
                /* Success!  Use the new buffer.  */
847
829
{
848
830
    TranslationBlock *tb;
849
831
 
850
 
    assert_tb_lock();
 
832
    assert_tb_locked();
851
833
 
852
834
    if (tcg_ctx.tb_ctx.nb_tbs >= tcg_ctx.code_gen_max_blocks) {
853
835
        return NULL;
862
844
/* Called with tb_lock held.  */
863
845
void tb_free(TranslationBlock *tb)
864
846
{
865
 
    assert_tb_lock();
 
847
    assert_tb_locked();
866
848
 
867
849
    /* In practice this is mostly used for single use temporary TB
868
850
       Ignore the hard cases and just back up if this TB happens to
1104
1086
    uint32_t h;
1105
1087
    tb_page_addr_t phys_pc;
1106
1088
 
1107
 
    assert_tb_lock();
 
1089
    assert_tb_locked();
1108
1090
 
1109
1091
    atomic_set(&tb->invalid, true);
1110
1092
 
1290
1272
        /* flush must be done */
1291
1273
        tb_flush(cpu);
1292
1274
        mmap_unlock();
 
1275
        /* Make the execution loop process the flush as soon as possible.  */
 
1276
        cpu->exception_index = EXCP_INTERRUPT;
1293
1277
        cpu_loop_exit(cpu);
1294
1278
    }
1295
1279
 
1419
1403
#ifdef CONFIG_SOFTMMU
1420
1404
void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end)
1421
1405
{
1422
 
    assert_tb_lock();
 
1406
    assert_tb_locked();
1423
1407
    tb_invalidate_phys_range_1(start, end);
1424
1408
}
1425
1409
#else
1462
1446
#endif /* TARGET_HAS_PRECISE_SMC */
1463
1447
 
1464
1448
    assert_memory_lock();
1465
 
    assert_tb_lock();
 
1449
    assert_tb_locked();
1466
1450
 
1467
1451
    p = page_find(start >> TARGET_PAGE_BITS);
1468
1452
    if (!p) {
1541
1525
#ifdef CONFIG_SOFTMMU
1542
1526
/* len must be <= 8 and start must be a multiple of len.
1543
1527
 * Called via softmmu_template.h when code areas are written to with
1544
 
 * tb_lock held.
 
1528
 * iothread mutex not held.
1545
1529
 */
1546
1530
void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
1547
1531
{
1743
1727
 
1744
1728
#ifndef CONFIG_USER_ONLY
1745
1729
/* in deterministic execution mode, instructions doing device I/Os
1746
 
   must be at the end of the TB */
 
1730
 * must be at the end of the TB.
 
1731
 *
 
1732
 * Called by softmmu_template.h, with iothread mutex not held.
 
1733
 */
1747
1734
void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
1748
1735
{
1749
1736
#if defined(TARGET_MIPS) || defined(TARGET_SH4)
1955
1942
 
1956
1943
void cpu_interrupt(CPUState *cpu, int mask)
1957
1944
{
 
1945
    g_assert(qemu_mutex_iothread_locked());
1958
1946
    cpu->interrupt_request |= mask;
1959
 
    cpu->tcg_exit_req = 1;
 
1947
    cpu->icount_decr.u16.high = -1;
1960
1948
}
1961
1949
 
1962
1950
/*