]> git.proxmox.com Git - mirror_qemu.git/commitdiff
ppc: Make alignment exceptions suck less
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 27 Jul 2016 06:56:41 +0000 (16:56 +1000)
committerDavid Gibson <david@gibson.dropbear.id.au>
Wed, 7 Sep 2016 02:40:10 +0000 (12:40 +1000)
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>
target-ppc/excp_helper.c
target-ppc/translate.c

index 882d529dbe7b4dafa3ab70e5e26f43b4e34fe66b..04ed4da1f463d68e0861e8c3f54c52e239c73dfc 100644 (file)
@@ -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) {
index bebd1cc49071410066fd03845d775973d71edf9e..6bb0ba97acfa096648edf95ad531def3b011817e 100644 (file)
@@ -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);