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.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJXFG3PAAoJEGw4ysog2bOSK/sQAL4jHiB83e2ob5pah7NviaWX
 3pwbvS2IrZkyeaNGVP4Qv1sghukX9E2FO1LlzqhsRGPt+W7MpfAC5kI3AC48Ivbx
 8JmPNl9o/fkXpK5p+BI503v1dLg1hy8H8sQXCXyzmyjK/+rv7gJP/3xpgTnGxT58
 aFxIevEYxK6noesMJVlxcDRt1WU/YxXfcYSXJvR4lNYqOKMYAL+jOMCcGCFYnTN3
 VOQpbp4koLrJ76ULK6t4cSieQZPp+ofSh3Y6VBvFg8SctNTXK4q3ZaC/pE00KuUd
 AIWhsKe7D1qmL5iyhqeys9JVrTdVIzG25m5U1hhpKLtv1jV9G5EgTYHsDx2cZF/9
 0hqMP7APhtCdH0ol2Qb83uBErupNzXkytnHJbqhBc+3RAUPM/VizUv3PiGGXqhuy
 tJCxdRkp2L4fWYByN0/8/3BgA3kxHszJbhTOWX3VhiEBjSygfPWH0p6rciJrrQYC
 IaPBIlIkAyoxCRIv9xjEwHHshRL1O5FpAGRgxEm4TqC7z/dyQCV0bYOzMA+7NbCJ
 dXEhRusagqE8ooa+9lZVs2PvzcbcCQIbPYtjnF4phBsxut/cK/YuSC7wWw49CjWj
 EWL3VVuzbdE9v01QkAjKvIwtLboO2yPhmnrvsn6YmsmB999Do4hpJnZ536SAGXOF
 jqDjSiDKIzKoiCfmtBUX
 =AnCp
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2016-04-18 11:11:45 +01:00
commit ba3899507a
4 changed files with 16 additions and 7 deletions

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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;
}