summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-04-18 11:11:45 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-04-18 11:11:45 +0100
commitba3899507acfaeee4815beee670c1d80f6f18570 (patch)
treeb0cf7066303228bcd21c9e1991247df2232eade8
parentadde0204e4edbebfeb77d244cad7d9d8be7ed7e0 (diff)
parentaa378598fea819b15c00d48048bedfa0dc631132 (diff)
downloadfocaccia-qemu-ba3899507acfaeee4815beee670c1d80f6f18570.tar.gz
focaccia-qemu-ba3899507acfaeee4815beee670c1d80f6f18570.zip
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.6-20160418' into staging
ppc patch queue for 2-16-04-18

Three bugfixe patches for 2.6 here.
* Two for bad implementation of some of the strong load/store
  instructions

* One for bad migration of the XER register.  This is a regression
  from 2.5, cause by a change in the way we represent at XER during
  runtime.

# gpg: Signature made Mon 18 Apr 2016 06:17:03 BST using RSA key ID 20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.6-20160418:
  ppc: Fix migration of the XER register
  ppc: Fix the bad exception NIP value and the range check in LSWX
  ppc: Fix the range check in the LSWI instruction

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target-ppc/cpu.h10
-rw-r--r--target-ppc/machine.c2
-rw-r--r--target-ppc/mem_helper.c5
-rw-r--r--target-ppc/translate.c6
4 files changed, 16 insertions, 7 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 9d4e43cf1f..5282533b38 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2415,6 +2415,16 @@ static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr)
     return msr & (1ULL << MSR_SF);
 }
 
+/**
+ * Check whether register rx is in the range between start and
+ * start + nregs (as needed by the LSWX and LSWI instructions)
+ */
+static inline bool lsw_reg_in_range(int start, int nregs, int rx)
+{
+    return (start + nregs <= 32 && rx >= start && rx < start + nregs) ||
+           (start + nregs > 32 && (rx >= start || rx < start + nregs - 32));
+}
+
 extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
 
 #include "exec/exec-all.h"
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 692121e983..46684fb933 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -136,7 +136,7 @@ static void cpu_pre_save(void *opaque)
 
     env->spr[SPR_LR] = env->lr;
     env->spr[SPR_CTR] = env->ctr;
-    env->spr[SPR_XER] = env->xer;
+    env->spr[SPR_XER] = cpu_read_xer(env);
 #if defined(TARGET_PPC64)
     env->spr[SPR_CFAR] = env->cfar;
 #endif
diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c
index 581d9faa23..6d584c9126 100644
--- a/target-ppc/mem_helper.c
+++ b/target-ppc/mem_helper.c
@@ -102,8 +102,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg,
 {
     if (likely(xer_bc != 0)) {
         int num_used_regs = (xer_bc + 3) / 4;
-        if (unlikely((ra != 0 && reg < ra && (reg + num_used_regs) > ra) ||
-                     (reg < rb && (reg + num_used_regs) > rb))) {
+        if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) ||
+                     lsw_reg_in_range(reg, num_used_regs, rb))) {
+            env->nip += 4;     /* Compensate the "nip - 4" from gen_lswx() */
             helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
                                        POWERPC_EXCP_INVAL |
                                        POWERPC_EXCP_INVAL_LSWX);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 6f0e7b4fac..b3860ecdea 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3227,10 +3227,8 @@ static void gen_lswi(DisasContext *ctx)
 
     if (nb == 0)
         nb = 32;
-    nr = nb / 4;
-    if (unlikely(((start + nr) > 32  &&
-                  start <= ra && (start + nr - 32) > ra) ||
-                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
+    nr = (nb + 3) / 4;
+    if (unlikely(lsw_reg_in_range(start, nr, ra))) {
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
         return;
     }