From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60675) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WQS6Y-0000Yc-Jw for qemu-devel@nongnu.org; Wed, 19 Mar 2014 21:49:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WQS6R-00042Z-Gf for qemu-devel@nongnu.org; Wed, 19 Mar 2014 21:49:10 -0400 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 20 Mar 2014 02:48:49 +0100 Message-Id: <1395280135-10644-8-git-send-email-afaerber@suse.de> In-Reply-To: <1395280135-10644-1-git-send-email-afaerber@suse.de> References: <1395280135-10644-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PULL for-2.0 07/13] spapr_hcall: Fix little-endian resource handling in H_SET_MODE List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Alexey Kardashevskiy , qemu-ppc@nongnu.org, =?UTF-8?q?Andreas=20F=C3=A4rber?= , Alexander Graf From: Alexey Kardashevskiy This changes resource code definitions to ones used in the host kernel. This fixes H_SET_MODE_RESOURCE_LE (switch between big endian and little endian) to sync registers from KVM before changing LPCR value. This adds a set_spr() helper to update an SPR in a CPU's context to avoid possible races and makes use of it to change LPCR. Signed-off-by: Alexey Kardashevskiy Reviewed-by: Greg Kurz Signed-off-by: Andreas F=C3=A4rber --- hw/ppc/spapr_hcall.c | 41 +++++++++++++++++++++++++++++++++-------- include/hw/ppc/spapr.h | 9 +++++++-- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 2ab55d5..0bae053 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -4,6 +4,36 @@ #include "hw/ppc/spapr.h" #include "mmu-hash64.h" =20 +struct SPRSyncState { + CPUState *cs; + int spr; + target_ulong value; + target_ulong mask; +}; + +static void do_spr_sync(void *arg) +{ + struct SPRSyncState *s =3D arg; + PowerPCCPU *cpu =3D POWERPC_CPU(s->cs); + CPUPPCState *env =3D &cpu->env; + + cpu_synchronize_state(s->cs); + env->spr[s->spr] &=3D ~s->mask; + env->spr[s->spr] |=3D s->value; +} + +static void set_spr(CPUState *cs, int spr, target_ulong value, + target_ulong mask) +{ + struct SPRSyncState s =3D { + .cs =3D cs, + .spr =3D spr, + .value =3D value, + .mask =3D mask + }; + run_on_cpu(cs, do_spr_sync, &s); +} + static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r, target_ulong pte_index) { @@ -689,7 +719,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPR= Environment *spapr, target_ulong value2 =3D args[3]; target_ulong ret =3D H_P2; =20 - if (resource =3D=3D H_SET_MODE_ENDIAN) { + if (resource =3D=3D H_SET_MODE_RESOURCE_LE) { if (value1) { ret =3D H_P3; goto out; @@ -698,22 +728,17 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPA= PREnvironment *spapr, ret =3D H_P4; goto out; } - switch (mflags) { case H_SET_MODE_ENDIAN_BIG: CPU_FOREACH(cs) { - PowerPCCPU *cp =3D POWERPC_CPU(cs); - CPUPPCState *env =3D &cp->env; - env->spr[SPR_LPCR] &=3D ~LPCR_ILE; + set_spr(cs, SPR_LPCR, 0, LPCR_ILE); } ret =3D H_SUCCESS; break; =20 case H_SET_MODE_ENDIAN_LITTLE: CPU_FOREACH(cs) { - PowerPCCPU *cp =3D POWERPC_CPU(cs); - CPUPPCState *env =3D &cp->env; - env->spr[SPR_LPCR] |=3D LPCR_ILE; + set_spr(cs, SPR_LPCR, LPCR_ILE, LPCR_ILE); } ret =3D H_SUCCESS; break; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 449fc7c..5fdac1e 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -153,8 +153,13 @@ typedef struct sPAPREnvironment { #define H_PP1 (1ULL<<(63-62)) #define H_PP2 (1ULL<<(63-63)) =20 -/* H_SET_MODE flags */ -#define H_SET_MODE_ENDIAN 4 +/* Values for 2nd argument to H_SET_MODE */ +#define H_SET_MODE_RESOURCE_SET_CIABR 1 +#define H_SET_MODE_RESOURCE_SET_DAWR 2 +#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 +#define H_SET_MODE_RESOURCE_LE 4 + +/* Flags for H_SET_MODE_RESOURCE_LE */ #define H_SET_MODE_ENDIAN_BIG 0 #define H_SET_MODE_ENDIAN_LITTLE 1 =20 --=20 1.8.4.5