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>
This commit is contained in:
parent
4e6d0920e7
commit
28876bf27d
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue