diff options
author | Alex Bennée <alex.bennee@linaro.org> | 2019-07-16 13:13:52 +0100 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2019-08-21 17:17:11 +1000 |
commit | 28876bf27d2792e6b16cfb5283b9fb959fc0ad12 (patch) | |
tree | 953ad59dd8b360d02713357917f961d21047ed1c /target | |
parent | 4e6d0920e7547e6af4bbac5ffe9adfe6ea621822 (diff) |
target/ppc: move opcode decode tables to PowerPCCPU
The opcode decode tables aren't really part of the CPUPPCState but an
internal implementation detail for the translator. This can cause
problems with memcpy in cpu_copy as any table created during
ppc_cpu_realize get written over causing a memory leak. To avoid this
move the tables into PowerPCCPU which is better suited to hold
internal implementation details.
Attempts to fix: https://bugs.launchpad.net/qemu/+bug/1836558
Cc: 1836558@bugs.launchpad.net
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20190716121352.302-1-alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target')
-rw-r--r-- | target/ppc/cpu.h | 8 | ||||
-rw-r--r-- | target/ppc/translate.c | 3 | ||||
-rw-r--r-- | target/ppc/translate_init.inc.c | 16 |
3 files changed, 13 insertions, 14 deletions
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 4ea33cf696..630a25c246 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1104,10 +1104,6 @@ struct CPUPPCState { bool resume_as_sreset; #endif - /* Those resources are used only during code translation */ - /* opcode handlers */ - opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN]; - /* Those resources are used only in QEMU core */ target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */ target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */ @@ -1191,6 +1187,10 @@ struct PowerPCCPU { int32_t node_id; /* NUMA node this CPU belongs to */ PPCHash64Options *hash64_opts; + /* Those resources are used only during code translation */ + /* opcode handlers */ + opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN]; + /* Fields related to migration compatibility hacks */ bool pre_2_8_migration; target_ulong mig_msr_mask; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 9f9553afb4..1afb31e855 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7858,6 +7858,7 @@ static bool ppc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { DisasContext *ctx = container_of(dcbase, DisasContext, base); + PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = cs->env_ptr; opc_handler_t **table, *handler; @@ -7875,7 +7876,7 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) opc3(ctx->opcode), opc4(ctx->opcode), ctx->le_mode ? "little" : "big"); ctx->base.pc_next += 4; - table = env->opcodes; + table = cpu->opcodes; handler = table[opc1(ctx->opcode)]; if (is_indirect_opcode(handler)) { table = ind_table(handler); diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 86fc8f2e31..9cd2033bb9 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9440,14 +9440,13 @@ static void fix_opcode_tables(opc_handler_t **ppc_opcodes) static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) { PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - CPUPPCState *env = &cpu->env; opcode_t *opc; - fill_new_table(env->opcodes, PPC_CPU_OPCODES_LEN); + fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN); for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { if (((opc->handler.type & pcc->insns_flags) != 0) || ((opc->handler.type2 & pcc->insns_flags2) != 0)) { - if (register_insn(env->opcodes, opc) < 0) { + if (register_insn(cpu->opcodes, opc) < 0) { error_setg(errp, "ERROR initializing PowerPC instruction " "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2, opc->opc3); @@ -9455,7 +9454,7 @@ static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) } } } - fix_opcode_tables(env->opcodes); + fix_opcode_tables(cpu->opcodes); fflush(stdout); fflush(stderr); } @@ -10023,7 +10022,6 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) { PowerPCCPU *cpu = POWERPC_CPU(dev); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - CPUPPCState *env = &cpu->env; Error *local_err = NULL; opc_handler_t **table, **table_2; int i, j, k; @@ -10035,11 +10033,11 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) } for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { - if (env->opcodes[i] == &invalid_handler) { + if (cpu->opcodes[i] == &invalid_handler) { continue; } - if (is_indirect_opcode(env->opcodes[i])) { - table = ind_table(env->opcodes[i]); + if (is_indirect_opcode(cpu->opcodes[i])) { + table = ind_table(cpu->opcodes[i]); for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { if (table[j] == &invalid_handler) { continue; @@ -10057,7 +10055,7 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) ~PPC_INDIRECT)); } } - g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] & + g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] & ~PPC_INDIRECT)); } } |