[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 16/30] target/ppc: Add SRR1 prefix indication to interrupt handler
From: |
Cédric Le Goater |
Subject: |
[PULL 16/30] target/ppc: Add SRR1 prefix indication to interrupt handlers |
Date: |
Mon, 26 Jun 2023 07:56:33 +0200 |
From: Nicholas Piggin <npiggin@gmail.com>
ISA v3.1 introduced prefix instructions. Among the changes, various
synchronous interrupts report whether they were caused by a prefix
instruction in (H)SRR1.
The case of instruction fetch that causes an HDSI due to access of a
process-scoped table faulting on the partition scoped translation is the
tricky one. As with ISIs and HISIs, this does not try to set the prefix
bit because there is no instruction image to be loaded. The HDSI needs
the originating access type to be passed through to the handler to
distinguish this from HDSIs that fault translating process scoped tables
originating from a load or store instruction (in that case the prefix
bit should be provided).
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[ clg: checkpatch issues ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
target/ppc/excp_helper.c | 73 +++++++++++++++++++++++++++++++++++++++-
target/ppc/mmu-radix64.c | 14 ++++++--
2 files changed, 83 insertions(+), 4 deletions(-)
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index a2801f6e6b6a..847f8a33beba 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -28,6 +28,7 @@
#include "trace.h"
#ifdef CONFIG_TCG
+#include "sysemu/tcg.h"
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
#endif
@@ -141,7 +142,7 @@ static inline bool insn_need_byteswap(CPUArchState *env)
return !!(env->msr & ((target_ulong)1 << MSR_LE));
}
-static uint32_t ppc_ldl_code(CPUArchState *env, hwaddr addr)
+static uint32_t ppc_ldl_code(CPUArchState *env, abi_ptr addr)
{
uint32_t insn = cpu_ldl_code(env, addr);
@@ -1348,6 +1349,72 @@ static bool books_vhyp_handles_hv_excp(PowerPCCPU *cpu)
return false;
}
+#ifdef CONFIG_TCG
+static bool is_prefix_insn(CPUPPCState *env, uint32_t insn)
+{
+ if (!(env->insns_flags2 & PPC2_ISA310)) {
+ return false;
+ }
+ return ((insn & 0xfc000000) == 0x04000000);
+}
+
+static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
+{
+ CPUPPCState *env = &cpu->env;
+
+ if (!tcg_enabled()) {
+ /*
+ * This does not load instructions and set the prefix bit correctly
+ * for injected interrupts with KVM. That may have to be discovered
+ * and set by the KVM layer before injecting.
+ */
+ return false;
+ }
+
+ switch (excp) {
+ case POWERPC_EXCP_HDSI:
+ /* HDSI PRTABLE_FAULT has the originating access type in error_code */
+ if ((env->spr[SPR_HDSISR] & DSISR_PRTABLE_FAULT) &&
+ (env->error_code == MMU_INST_FETCH)) {
+ /*
+ * Fetch failed due to partition scope translation, so prefix
+ * indication is not relevant (and attempting to load the
+ * instruction at NIP would cause recursive faults with the same
+ * translation).
+ */
+ break;
+ }
+ /* fall through */
+ case POWERPC_EXCP_MCHECK:
+ case POWERPC_EXCP_DSI:
+ case POWERPC_EXCP_DSEG:
+ case POWERPC_EXCP_ALIGN:
+ case POWERPC_EXCP_PROGRAM:
+ case POWERPC_EXCP_FPU:
+ case POWERPC_EXCP_TRACE:
+ case POWERPC_EXCP_HV_EMU:
+ 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;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+#else
+static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
+{
+ return false;
+}
+#endif
+
static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
{
CPUState *cs = CPU(cpu);
@@ -1395,6 +1462,10 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
vector |= env->excp_prefix;
+ if (is_prefix_insn_excp(cpu, excp)) {
+ msr |= PPC_BIT(34);
+ }
+
switch (excp) {
case POWERPC_EXCP_MCHECK: /* Machine check exception */
if (!FIELD_EX64(env->msr, MSR, ME)) {
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 1fc1ba3ecf22..920084bd8ff2 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -145,6 +145,13 @@ static void ppc_radix64_raise_hsi(PowerPCCPU *cpu,
MMUAccessType access_type,
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
+ env->error_code = 0;
+ if (cause & DSISR_PRTABLE_FAULT) {
+ /* HDSI PRTABLE_FAULT gets the originating access type in error_code */
+ env->error_code = access_type;
+ access_type = MMU_DATA_LOAD;
+ }
+
qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx" 0x%"
HWADDR_PRIx" cause %08x\n",
__func__, access_str(access_type),
@@ -166,7 +173,6 @@ static void ppc_radix64_raise_hsi(PowerPCCPU *cpu,
MMUAccessType access_type,
env->spr[SPR_HDSISR] = cause;
env->spr[SPR_HDAR] = eaddr;
env->spr[SPR_ASDR] = g_raddr;
- env->error_code = 0;
break;
default:
g_assert_not_reached();
@@ -369,13 +375,14 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid,
ppc_v3_pate_t *pate)
}
static int ppc_radix64_partition_scoped_xlate(PowerPCCPU *cpu,
- MMUAccessType access_type,
+ MMUAccessType orig_access_type,
vaddr eaddr, hwaddr g_raddr,
ppc_v3_pate_t pate,
hwaddr *h_raddr, int *h_prot,
int *h_page_size, bool pde_addr,
int mmu_idx, bool guest_visible)
{
+ MMUAccessType access_type = orig_access_type;
int fault_cause = 0;
hwaddr pte_addr;
uint64_t pte;
@@ -404,7 +411,8 @@ static int ppc_radix64_partition_scoped_xlate(PowerPCCPU
*cpu,
fault_cause |= DSISR_PRTABLE_FAULT;
}
if (guest_visible) {
- ppc_radix64_raise_hsi(cpu, access_type, eaddr, g_raddr,
fault_cause);
+ ppc_radix64_raise_hsi(cpu, orig_access_type,
+ eaddr, g_raddr, fault_cause);
}
return 1;
}
--
2.41.0
- [PULL 09/30] target/ppc: Fix timer register accessors when !KVM, (continued)
- [PULL 13/30] ppc/spapr: Move spapr nested HV to a new file, Cédric Le Goater, 2023/06/26
- [PULL 17/30] target/ppc: Implement HEIR SPR, Cédric Le Goater, 2023/06/26
- [PULL 14/30] target/ppc: Fix instruction loading endianness in alignment interrupt, Cédric Le Goater, 2023/06/26
- [PULL 12/30] ppc/spapr: load and store l2 state with helper functions, Cédric Le Goater, 2023/06/26
- [PULL 15/30] target/ppc: Change partition-scope translate interface, Cédric Le Goater, 2023/06/26
- [PULL 16/30] target/ppc: Add SRR1 prefix indication to interrupt handlers,
Cédric Le Goater <=
- [PULL 23/30] target/ppc: Add msgsnd/p and DPDES SMT support, Cédric Le Goater, 2023/06/26
- [PULL 21/30] target/ppc: Add initial flags and helpers for SMT support, Cédric Le Goater, 2023/06/26
- [PULL 24/30] hw/ppc/spapr: Test whether TCG is enabled with tcg_enabled(), Cédric Le Goater, 2023/06/26
- [PULL 26/30] tests/avocado: boot ppc64 pseries to Linux VFS mount, Cédric Le Goater, 2023/06/26
- [PULL 19/30] target/ppc: Better CTRL SPR implementation, Cédric Le Goater, 2023/06/26
- [PULL 29/30] pnv/xive2: Check TIMA special ops against a dedicated array for P10, Cédric Le Goater, 2023/06/26
- [PULL 22/30] target/ppc: Add support for SMT CTRL register, Cédric Le Goater, 2023/06/26
- [PULL 18/30] target/ppc: Add ISA v3.1 LEV indication in SRR1 for system call interrupts, Cédric Le Goater, 2023/06/26
- [PULL 20/30] target/ppc: Fix sc instruction handling of LEV field, Cédric Le Goater, 2023/06/26
- [PULL 25/30] spapr: TCG allow up to 8-thread SMT on POWER8 and newer CPUs, Cédric Le Goater, 2023/06/26