aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2016-07-27 16:56:41 +1000
committerDavid Gibson <david@gibson.dropbear.id.au>2016-09-07 12:40:10 +1000
commit3433b732a4c9abb413eb39a6badb63e83ad2288c (patch)
tree82a1c93d253ce3f35acd9de6892e66d2839ffdce
parentb00a3b3648c32cd1d2baaeef6d6a81e8d9341259 (diff)
downloadqemu-3433b732a4c9abb413eb39a6badb63e83ad2288c.zip
qemu-3433b732a4c9abb413eb39a6badb63e83ad2288c.tar.gz
qemu-3433b732a4c9abb413eb39a6badb63e83ad2288c.tar.bz2
ppc: Make alignment exceptions suck less
The current alignment exception generation tries to load the opcode to put in DSISR from a context where a cpu_ldl_code() is really not a good idea. It might fault and longjmp out and that's not something we want happening here. Instead, pass the releavant opcode bits via the error_code. There are a couple of cases of alignment interrupts that won't set anything, the ones coming from access to direct store segments, but that doesn't happen in practice, nobody used direct store segments and they are gone from newer chips. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r--target-ppc/excp_helper.c9
-rw-r--r--target-ppc/translate.c2
2 files changed, 6 insertions, 5 deletions
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 882d529..04ed4da 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -260,11 +260,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
}
break;
case POWERPC_EXCP_ALIGN: /* Alignment exception */
- /* XXX: this is false */
/* Get rS/rD and rA from faulting opcode */
- /* Broken for LE mode */
- env->spr[SPR_DSISR] |= (cpu_ldl_code(env, env->nip)
- & 0x03FF0000) >> 16;
+ /* Note: the opcode fields will not be set properly for a direct
+ * store load/store, but nobody cares as nobody actually uses
+ * direct store segments.
+ */
+ env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
break;
case POWERPC_EXCP_PROGRAM: /* Program exception */
switch (env->error_code & ~0xF) {
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index bebd1cc..6bb0ba9 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2417,7 +2417,7 @@ static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
tcg_gen_andi_tl(t0, EA, mask);
tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
- t2 = tcg_const_i32(0);
+ t2 = tcg_const_i32(ctx->opcode & 0x03FF0000);
gen_update_nip(ctx, ctx->nip - 4);
gen_helper_raise_exception_err(cpu_env, t1, t2);
tcg_temp_free_i32(t1);