[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 02/47] target/ppc: Fix crash on machine check caused by ifetch
From: |
Nicholas Piggin |
Subject: |
[PULL 02/47] target/ppc: Fix crash on machine check caused by ifetch |
Date: |
Sat, 24 Feb 2024 01:41:21 +1000 |
is_prefix_insn_excp() loads the first word of the instruction address
which caused an exception, to determine whether or not it was prefixed
so the prefix bit can be set in [H]SRR1.
This works if the instruction image can be loaded, but if the exception
was caused by an ifetch, this load could fail and cause a recursive
exception and crash. Machine checks caused by ifetch are not excluded
from the prefix check and can crash (see issue 2108 for an example).
Fix this by excluding machine checks caused by ifetch from the prefix
check.
Cc: qemu-stable@nongnu.org
Acked-by: Cédric Le Goater <clg@kaod.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2108
Fixes: 55a7fa34f89 ("target/ppc: Machine check on invalid real address access
on POWER9/10")
Fixes: 5a5d3b23cb2 ("target/ppc: Add SRR1 prefix indication to interrupt
handlers")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/excp_helper.c | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 2ec6429e36..98952de267 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1312,6 +1312,10 @@ static bool is_prefix_insn_excp(PowerPCCPU *cpu, int
excp)
{
CPUPPCState *env = &cpu->env;
+ if (!(env->insns_flags2 & PPC2_ISA310)) {
+ return false;
+ }
+
if (!tcg_enabled()) {
/*
* This does not load instructions and set the prefix bit correctly
@@ -1322,6 +1326,15 @@ static bool is_prefix_insn_excp(PowerPCCPU *cpu, int
excp)
}
switch (excp) {
+ case POWERPC_EXCP_MCHECK:
+ if (!(env->error_code & PPC_BIT(42))) {
+ /*
+ * Fetch attempt caused a machine check, so attempting to fetch
+ * again would cause a recursive machine check.
+ */
+ return false;
+ }
+ break;
case POWERPC_EXCP_HDSI:
/* HDSI PRTABLE_FAULT has the originating access type in error_code */
if ((env->spr[SPR_HDSISR] & DSISR_PRTABLE_FAULT) &&
@@ -1332,10 +1345,10 @@ static bool is_prefix_insn_excp(PowerPCCPU *cpu, int
excp)
* instruction at NIP would cause recursive faults with the same
* translation).
*/
- break;
+ return false;
}
- /* fall through */
- case POWERPC_EXCP_MCHECK:
+ break;
+
case POWERPC_EXCP_DSI:
case POWERPC_EXCP_DSEG:
case POWERPC_EXCP_ALIGN:
@@ -1346,17 +1359,13 @@ static bool is_prefix_insn_excp(PowerPCCPU *cpu, int
excp)
case POWERPC_EXCP_VPU:
case POWERPC_EXCP_VSXU:
case POWERPC_EXCP_FU:
- case POWERPC_EXCP_HV_FU: {
- uint32_t insn = ppc_ldl_code(env, env->nip);
- if (is_prefix_insn(env, insn)) {
- return true;
- }
+ case POWERPC_EXCP_HV_FU:
break;
- }
default:
- break;
+ return false;
}
- return false;
+
+ return is_prefix_insn(env, ppc_ldl_code(env, env->nip));
}
#else
static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
@@ -3224,6 +3233,7 @@ void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr
physaddr,
switch (env->excp_model) {
#if defined(TARGET_PPC64)
+ case POWERPC_EXCP_POWER8:
case POWERPC_EXCP_POWER9:
case POWERPC_EXCP_POWER10:
/*
@@ -3245,6 +3255,10 @@ void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr
physaddr,
env->error_code |= PPC_BIT(42);
} else { /* Fetch */
+ /*
+ * is_prefix_insn_excp() tests !PPC_BIT(42) to avoid fetching
+ * the instruction, so that must always be clear for fetches.
+ */
env->error_code = PPC_BIT(36) | PPC_BIT(44) | PPC_BIT(45);
}
break;
--
2.42.0
- [PULL 03/47] tests/avocado: mark boot_linux.py long runtime instead of flaky, (continued)
- [PULL 03/47] tests/avocado: mark boot_linux.py long runtime instead of flaky, Nicholas Piggin, 2024/02/23
- [PULL 14/47] hw/ppc/spapr_hcall: Rename {softmmu -> vhyp_mmu}_resize_hpt_pr, Nicholas Piggin, 2024/02/23
- [PULL 18/47] ppc/spapr: change pseries machine default to POWER10 CPU, Nicholas Piggin, 2024/02/23
- [PULL 27/47] misc: Add a pca9554 GPIO device model, Nicholas Piggin, 2024/02/23
- [PULL 01/47] target/ppc: Fix lxv/stxv MSR facility check, Nicholas Piggin, 2024/02/23
- [PULL 05/47] tests/avocado: ppc add powernv10 boot_linux_console test, Nicholas Piggin, 2024/02/23
- [PULL 09/47] tests/avocado: Use default CPU for pseries machine, Nicholas Piggin, 2024/02/23
- [PULL 11/47] target/ppc: Rename registers to match ISA, Nicholas Piggin, 2024/02/23
- [PULL 12/47] hw/ppc/spapr: Add missing license, Nicholas Piggin, 2024/02/23
- [PULL 17/47] ppc/spapr: Initialize max_cpus limit to SPAPR_IRQ_NR_IPIS., Nicholas Piggin, 2024/02/23
- [PULL 02/47] target/ppc: Fix crash on machine check caused by ifetch,
Nicholas Piggin <=
- [PULL 25/47] ppc/pnv: Wire up pca9552 GPIO pins for PCIe hotplug power control, Nicholas Piggin, 2024/02/23
- [PULL 26/47] ppc/pnv: Use resettable interface to reset child I2C buses, Nicholas Piggin, 2024/02/23
- [PULL 28/47] ppc/pnv: Add a pca9554 I2C device to powernv10-rainier, Nicholas Piggin, 2024/02/23
- [PULL 19/47] spapr: Tag pseries-2.1 - 2.11 machines as deprecated, Nicholas Piggin, 2024/02/23
- [PULL 31/47] hw/ppc: Add N1 chiplet model, Nicholas Piggin, 2024/02/23
- [PULL 39/47] ppc/pnv: Implement the ChipTOD to Core transfer, Nicholas Piggin, 2024/02/23
- [PULL 42/47] target/ppc: Fix 440 tlbwe TLB invalidation gaps, Nicholas Piggin, 2024/02/23
- [PULL 47/47] target/ppc: optimise ppcemb_tlb_t flushing, Nicholas Piggin, 2024/02/23
- [PULL 04/47] tests/avocado: improve flaky ppc/pnv boot_linux_console.py test, Nicholas Piggin, 2024/02/23
- [PULL 08/47] tests/avocado: ppc add hypervisor tests, Nicholas Piggin, 2024/02/23