From 55a7fa34f8982f22497b2453787336acc7f79a7c Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 3 Jul 2023 22:03:01 +1000 Subject: target/ppc: Machine check on invalid real address access on POWER9/10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ppc currently silently accepts invalid real address access. Catch these and turn them into machine checks on POWER9/10 machines. Signed-off-by: Nicholas Piggin Reviewed-by: Cédric Le Goater Message-ID: <20230703120301.45313-1-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'target/ppc/excp_helper.c') diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 7683ea0..003805b 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1428,7 +1428,9 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp) /* machine check exceptions don't have ME set */ new_msr &= ~((target_ulong)1 << MSR_ME); + msr |= env->error_code; break; + case POWERPC_EXCP_DSI: /* Data storage exception */ trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); break; @@ -3188,5 +3190,52 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, env->error_code = insn & 0x03FF0000; cpu_loop_exit(cs); } + +void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, + vaddr vaddr, unsigned size, + MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr) +{ + CPUPPCState *env = cs->env_ptr; + + switch (env->excp_model) { +#if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER9: + case POWERPC_EXCP_POWER10: + /* + * Machine check codes can be found in processor User Manual or + * Linux or skiboot source. + */ + if (access_type == MMU_DATA_LOAD) { + env->spr[SPR_DAR] = vaddr; + env->spr[SPR_DSISR] = PPC_BIT(57); + env->error_code = PPC_BIT(42); + + } else if (access_type == MMU_DATA_STORE) { + /* + * MCE for stores in POWER is asynchronous so hardware does + * not set DAR, but QEMU can do better. + */ + env->spr[SPR_DAR] = vaddr; + env->error_code = PPC_BIT(36) | PPC_BIT(43) | PPC_BIT(45); + env->error_code |= PPC_BIT(42); + + } else { /* Fetch */ + env->error_code = PPC_BIT(36) | PPC_BIT(44) | PPC_BIT(45); + } + break; +#endif + default: + /* + * TODO: Check behaviour for other CPUs, for now do nothing. + * Could add a basic MCE even if real hardware ignores. + */ + return; + } + + cs->exception_index = POWERPC_EXCP_MCHECK; + cpu_loop_exit_restore(cs, retaddr); +} #endif /* CONFIG_TCG */ #endif /* !CONFIG_USER_ONLY */ -- cgit v1.1