From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42762) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YJDyd-00010B-AE for qemu-devel@nongnu.org; Wed, 04 Feb 2015 23:23:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YJDyZ-0006Vu-CZ for qemu-devel@nongnu.org; Wed, 04 Feb 2015 23:23:39 -0500 Date: Thu, 5 Feb 2015 15:23:45 +1100 From: David Gibson Message-ID: <20150205042345.GO25675@voom.fritz.box> References: <1422523650-2888-1-git-send-email-aik@ozlabs.ru> <1422523650-2888-17-git-send-email-aik@ozlabs.ru> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="5PFZVUeDPxlnBcQp" Content-Disposition: inline In-Reply-To: <1422523650-2888-17-git-send-email-aik@ozlabs.ru> Subject: Re: [Qemu-devel] [PATCH v4 16/18] spapr_rtas_ddw: Workaround broken LE guests List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexey Kardashevskiy Cc: Alex Williamson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Alexander Graf --5PFZVUeDPxlnBcQp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Jan 29, 2015 at 08:27:28PM +1100, Alexey Kardashevskiy wrote: > Recent kernels do parse results of what DDW RTAS calls return incorrectly > if compiled with LITTLE_ENDIAN=3Dyes. >=20 > This adds special handling for such guests. I don't really follow this commit message. You need to justify including this ugly workaround for incorrect guests. What are the guests that are out in the field which will trigger this behav= iour? >=20 > Signed-off-by: Alexey Kardashevskiy > --- > hw/ppc/spapr_rtas.c | 29 +++++++++++++++++++++++++++++ > hw/ppc/spapr_rtas_ddw.c | 40 ++++++++++++++++++++++++++++++++++++++++ > include/hw/ppc/spapr.h | 2 ++ > 3 files changed, 71 insertions(+) >=20 > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c > index 2ec2a8e..c3dee94 100644 > --- a/hw/ppc/spapr_rtas.c > +++ b/hw/ppc/spapr_rtas.c > @@ -293,12 +293,15 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu, > static struct rtas_call { > const char *name; > spapr_rtas_fn fn; > + spapr_rtas_fn fn_wa; /* workaround helper */ > } rtas_table[RTAS_TOKEN_MAX - RTAS_TOKEN_BASE]; > =20 > target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr, > uint32_t token, uint32_t nargs, target_ulon= g args, > uint32_t nret, target_ulong rets) > { > + uint32_t tokensw =3D bswap32(token); > + > if ((token >=3D RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX)) { > struct rtas_call *call =3D rtas_table + (token - RTAS_TOKEN_BASE= ); > =20 > @@ -308,6 +311,16 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRE= nvironment *spapr, > } > } > =20 > + /* Workaround for LE guests */ > + if ((tokensw >=3D RTAS_TOKEN_BASE) && (tokensw < RTAS_TOKEN_MAX)) { > + struct rtas_call *call =3D rtas_table + (tokensw - RTAS_TOKEN_BA= SE); > + > + if (call->fn_wa) { > + call->fn_wa(cpu, spapr, tokensw, nargs, args, nret, rets); > + return H_SUCCESS; > + } > + } > + > /* HACK: Some Linux early debug code uses RTAS display-character, > * but assumes the token value is 0xa (which it is on some real > * machines) without looking it up in the device tree. This > @@ -340,6 +353,22 @@ void spapr_rtas_register(int token, const char *name= , spapr_rtas_fn fn) > rtas_table[token].fn =3D fn; > } > =20 > +void spapr_rtas_register_wrong_endian(int token, spapr_rtas_fn fn) > +{ > + if (!((token >=3D RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX))) { > + fprintf(stderr, "RTAS invalid token 0x%x\n", token); > + exit(1); > + } > + > + token -=3D RTAS_TOKEN_BASE; > + if (!rtas_table[token].fn) { > + fprintf(stderr, "RTAS token %x must be initialized to allow work= around\n", > + token); > + exit(1); > + } > + rtas_table[token].fn_wa =3D fn; > +} > + > int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr, > hwaddr rtas_size) > { > diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c > index af70601..56eae9f 100644 > --- a/hw/ppc/spapr_rtas_ddw.c > +++ b/hw/ppc/spapr_rtas_ddw.c > @@ -278,6 +278,41 @@ param_error_exit: > rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); > } > =20 > +#define SPAPR_RTAS_DDW_SWAP(n) rtas_st(rets, (n), bswap32(rtas_ld(rets, = (n)))) > + > +static void rtas_ibm_query_pe_dma_window_wrong_endian(PowerPCCPU *cpu, > + sPAPREnvironment *= spapr, > + uint32_t token, > + uint32_t nargs, > + target_ulong args, > + uint32_t nret, > + target_ulong rets) > +{ > + rtas_ibm_query_pe_dma_window(cpu, spapr, token, nargs, args, nret, r= ets); > + > + SPAPR_RTAS_DDW_SWAP(0); > + SPAPR_RTAS_DDW_SWAP(1); > + SPAPR_RTAS_DDW_SWAP(2); > + SPAPR_RTAS_DDW_SWAP(3); > + SPAPR_RTAS_DDW_SWAP(4); > +} > + > +static void rtas_ibm_create_pe_dma_window_wrong_endian(PowerPCCPU *cpu, > + sPAPREnvironment = *spapr, > + uint32_t token, > + uint32_t nargs, > + target_ulong args, > + uint32_t nret, > + target_ulong rets) > +{ > + rtas_ibm_create_pe_dma_window(cpu, spapr, token, nargs, args, nret, = rets); > + > + SPAPR_RTAS_DDW_SWAP(0); > + SPAPR_RTAS_DDW_SWAP(1); > + SPAPR_RTAS_DDW_SWAP(2); > + SPAPR_RTAS_DDW_SWAP(3); > +} > + > static void spapr_rtas_ddw_init(void) > { > spapr_rtas_register(RTAS_IBM_QUERY_PE_DMA_WINDOW, > @@ -292,6 +327,11 @@ static void spapr_rtas_ddw_init(void) > spapr_rtas_register(RTAS_IBM_RESET_PE_DMA_WINDOW, > "ibm,reset-pe-dma-window", > rtas_ibm_reset_pe_dma_window); > + > + spapr_rtas_register_wrong_endian(RTAS_IBM_QUERY_PE_DMA_WINDOW, > + rtas_ibm_query_pe_dma_window_wrong_= endian); > + spapr_rtas_register_wrong_endian(RTAS_IBM_CREATE_PE_DMA_WINDOW, > + rtas_ibm_create_pe_dma_window_wrong= _endian); > } > =20 > type_init(spapr_rtas_ddw_init) > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index 5f4e137..bf8e4a6 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -435,6 +435,8 @@ typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPRE= nvironment *spapr, > uint32_t nargs, target_ulong args, > uint32_t nret, target_ulong rets); > void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn); > +void spapr_rtas_register_wrong_endian(int token, spapr_rtas_fn fn); > + > target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr, > uint32_t token, uint32_t nargs, target_ulon= g args, > uint32_t nret, target_ulong rets); --=20 David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson --5PFZVUeDPxlnBcQp Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJU0vBRAAoJEGw4ysog2bOS1GMQANbEOOKcGGWGMLhB4LrSFHJs hdqaE7j3MRTutWEEQYvGy/tKXwtSKX8/bejMnRkRQs1QAunFp8aA8c6qfKmm+llV tVzx2iTRi7iuBm+bier7VB9umIc6JR1n02pJaNix8r61JyvSiPjG3IXIk23kBvpO HL6SwuiaEXs1dptDtuVtot+R/BEk1ECQlZUSLJ8oUtlh7a/taNmC9e62hiL4Dv4z gvoUB165gSh9lW5fsEFRd3gLm6ur/UlN/VaFgaz1Oisl9O1ZOnJuv6pXVrZeJW1Y RqBepjqhWwQ8JN48N5ZzdYNMc2jfIHOZrUzQLejwI61rY3G1Xt+LVbotPSi5VqTp 3LaABIdwhfKpJTeNoiseNIGHyPgtcQdIYtWeVcxXE9Y2DwS2IoGfhzAdxDRzoxXW Dzsv++vBk6K43Y/53QtM15JueC11Y/M8ZQE+EWLjtIW2CgwAuLvvnugG9tMyHR0O bnn+Lwj4gzfPKpB0JXutJiEqGjcVd7DuHGuT6dFhxBJfrzDvfi6OVF1EleYX6NLQ Eu6dfJdEkm+2EsKbvyFozbKjyisDogamUg8A2Da2xgPxq7Y+8u7GKRfOoHwRko4h TP8SXCaKDWacVz+hv86aIyqgdKXhUzfAbVwvRkwr588tpev4u69WevPSyl3TznRg U5Zs7muDh4w/k87ES1/m =qC8b -----END PGP SIGNATURE----- --5PFZVUeDPxlnBcQp--