From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Gibson Subject: Re: [PATCH v3] powerpc: Add tests for sPAPR h-calls Date: Thu, 3 Mar 2016 10:23:32 +1100 Message-ID: <20160303102332.66345df6@voom.fritz.box> References: <1456908043-11184-1-git-send-email-thuth@redhat.com> <56D6BB7B.70401@redhat.com> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; boundary="Sig_/wzicHYQ+/NYNyUSV1XMciXz"; protocol="application/pgp-signature" Cc: Thomas Huth , kvm@vger.kernel.org, kvm-ppc@vger.kernel.org, drjones@redhat.com To: Laurent Vivier Return-path: Received: from mx1.redhat.com ([209.132.183.28]:34612 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751454AbcCBXXq (ORCPT ); Wed, 2 Mar 2016 18:23:46 -0500 In-Reply-To: <56D6BB7B.70401@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: --Sig_/wzicHYQ+/NYNyUSV1XMciXz Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable On Wed, 2 Mar 2016 11:07:55 +0100 Laurent Vivier wrote: > On 02/03/2016 09:40, Thomas Huth wrote: > > Introduce a test for sPAPR hypercalls, starting with the > > three hypercalls H_SET_SPRG0, H_PAGE_INIT and H_RANDOM. > >=20 > > Signed-off-by: Thomas Huth > > --- > > v3: > > - Use report_xfail() in H_RANDOM test to report whether the > > h-call is available or not > >=20 > > v2: > > - Rebased to the final version of Andrew's initial ppc64 > > support patches that got merged yesterday > > - Added a test for the H_RANDOM hypercall > >=20 > > Please note that you need the latest QEMU development version > > since some of the hypercalls have only been added recently. > >=20 > > In case somebody wants to review the description of the h-calls, you > > can find them in LoPAPR, chapters 14.5.4.3.1, 14.5.4.3.3 and 14.15.1. > > See: https://members.openpowerfoundation.org/document/dl/469 > >=20 > > lib/powerpc/asm/hcall.h | 3 + > > powerpc/Makefile.common | 5 +- > > powerpc/spapr_hcall.c | 167 ++++++++++++++++++++++++++++++++++++++++= ++++++++ > > powerpc/unittests.cfg | 3 + > > 4 files changed, 177 insertions(+), 1 deletion(-) > > create mode 100644 powerpc/spapr_hcall.c > >=20 > > diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h > > index 750c655..f6f9ea8 100644 > > --- a/lib/powerpc/asm/hcall.h > > +++ b/lib/powerpc/asm/hcall.h > > @@ -15,8 +15,11 @@ > > #define H_PRIVILEGE -3 > > #define H_PARAMETER -4 > > =20 > > +#define H_SET_SPRG0 0x24 > > #define H_SET_DABR 0x28 > > +#define H_PAGE_INIT 0x2c > > #define H_PUT_TERM_CHAR 0x58 > > +#define H_RANDOM 0x300 > > =20 > > #ifndef __ASSEMBLY__ > > /* > > diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common > > index b526668..2ce6494 100644 > > --- a/powerpc/Makefile.common > > +++ b/powerpc/Makefile.common > > @@ -5,7 +5,8 @@ > > # > > =20 > > tests-common =3D \ > > - $(TEST_DIR)/selftest.elf > > + $(TEST_DIR)/selftest.elf \ > > + $(TEST_DIR)/spapr_hcall.elf > > =20 > > all: $(TEST_DIR)/boot_rom.bin test_cases > > =20 > > @@ -63,3 +64,5 @@ generated_files =3D $(asm-offsets) > > test_cases: $(generated_files) $(tests-common) $(tests) > > =20 > > $(TEST_DIR)/selftest.elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/selftest.o > > + > > +$(TEST_DIR)/spapr_hcall.elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/spapr_= hcall.o > > diff --git a/powerpc/spapr_hcall.c b/powerpc/spapr_hcall.c > > new file mode 100644 > > index 0000000..46731e1 > > --- /dev/null > > +++ b/powerpc/spapr_hcall.c > > @@ -0,0 +1,167 @@ > > +/* > > + * Test sPAPR hypervisor calls (aka. h-calls) > > + * > > + * Copyright 2016 Thomas Huth, Red Hat Inc. > > + * > > + * This work is licensed under the terms of the GNU LGPL, version 2. > > + */ > > +#include > > +#include > > +#include > > +#include > > + > > +#define PAGE_SIZE 4096 > > + > > +#define H_ZERO_PAGE (1UL << (63-48)) > > +#define H_COPY_PAGE (1UL << (63-49)) > > + > > +#define mfspr(nr) ({ \ > > + uint64_t ret; \ > > + asm volatile("mfspr %0,%1" : "=3Dr"(ret) : "i"(nr)); \ > > + ret; \ > > +}) > > + > > +#define SPR_SPRG0 0x110 > > + > > +/** > > + * Test the H_SET_SPRG0 h-call by setting some values and checking whe= ther > > + * the SPRG0 register contains the correct values afterwards > > + */ > > +static void test_h_set_sprg0(int argc, char **argv) > > +{ > > + uint64_t sprg0, sprg0_orig; > > + int rc; > > + > > + if (argc > 1) > > + report_abort("Unsupported argument: '%s'", argv[1]); > > + > > + sprg0_orig =3D mfspr(SPR_SPRG0); > > + > > + rc =3D hcall(H_SET_SPRG0, 0xcafebabedeadbeefULL); > > + sprg0 =3D mfspr(SPR_SPRG0); > > + report("sprg0 =3D 0xcafebabedeadbeef", > > + rc =3D=3D H_SUCCESS && sprg0 =3D=3D 0xcafebabedeadbeefULL); > > + > > + rc =3D hcall(H_SET_SPRG0, 0xaaaaaaaa55555555ULL); > > + sprg0 =3D mfspr(SPR_SPRG0); > > + report("sprg0 =3D 0xaaaaaaaa55555555", > > + rc =3D=3D H_SUCCESS && sprg0 =3D=3D 0xaaaaaaaa55555555ULL); > > + > > + rc =3D hcall(H_SET_SPRG0, sprg0_orig); > > + sprg0 =3D mfspr(SPR_SPRG0); > > + report("sprg0 =3D 0x%llx", > > + rc =3D=3D H_SUCCESS && sprg0 =3D=3D sprg0_orig, sprg0_orig); > > +} > > + > > +/** > > + * Test the H_PAGE_INIT h-call by using it to clear and to copy a page= , and > > + * by checking for the correct values in the destination page afterwar= ds > > + */ > > +static void test_h_page_init(int argc, char **argv) > > +{ > > + u8 *dst, *src; > > + int rc; > > + > > + if (argc > 1) > > + report_abort("Unsupported argument: '%s'", argv[1]); > > + > > + dst =3D memalign(PAGE_SIZE, PAGE_SIZE); > > + src =3D memalign(PAGE_SIZE, PAGE_SIZE); > > + if (!dst || !src) > > + report_abort("Failed to alloc memory"); > > + > > + memset(dst, 0xaa, PAGE_SIZE); > > + rc =3D hcall(H_PAGE_INIT, H_ZERO_PAGE, dst, src); > > + report("h_zero_page", rc =3D=3D H_SUCCESS && *(uint64_t*)dst =3D=3D 0= ); > > + > > + *(uint64_t*)src =3D 0xbeefc0dedeadcafeULL; > > + rc =3D hcall(H_PAGE_INIT, H_COPY_PAGE, dst, src); > > + report("h_copy_page", > > + rc =3D=3D H_SUCCESS && *(uint64_t*)dst =3D=3D 0xbeefc0dedeadcafeULL); > > + > > + *(uint64_t*)src =3D 0x9abcdef012345678ULL; > > + rc =3D hcall(H_PAGE_INIT, H_COPY_PAGE|H_ZERO_PAGE, dst, src); > > + report("h_copy_page+h_zero_page", > > + rc =3D=3D H_SUCCESS && *(uint64_t*)dst =3D=3D 0x9abcdef012345678ULL= ); > > + > > + rc =3D hcall(H_PAGE_INIT, H_ZERO_PAGE, dst + 0x123, src); > > + report("h_zero_page unaligned dst", rc =3D=3D H_PARAMETER); > > + > > + rc =3D hcall(H_PAGE_INIT, H_COPY_PAGE, dst, src + 0x123); > > + report("h_copy_page unaligned src", rc =3D=3D H_PARAMETER); > > +} > > + > > +static int h_random(uint64_t *val) > > +{ > > + register uint64_t r3 asm("r3") =3D H_RANDOM; > > + register uint64_t r4 asm("r4"); > > + > > + asm volatile (" sc 1 " : "+r"(r3), "=3Dr"(r4) : "r"(r3)); =20 >=20 > as you use "+r" with r3 in the output operands field, I think you don't > have to declare it in the input operands field. More importantly, I think a hypercall is allowed to clobber any of the volatile registers (r0 & r3..r12), so they probably need to be declared in the clobbers as well. --=20 David Gibson Senior Software Engineer, Virtualization, Red Hat --Sig_/wzicHYQ+/NYNyUSV1XMciXz Content-Type: application/pgp-signature Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJW13X1AAoJEGw4ysog2bOSnjkP/2FRONmK17XDVUhd5T8RuYrf wWGMld1ntb/9bd8J09QU6ZWZGxtEyr/yJMjxW2mYg3QH1i/fVYVsPhgtSvZl82gm nhUD3AhjBJjP2Nn6vBmebuHvMzwRclDAn/fwVVN79gK+0gjGFlkTFpvm9QDo3zYH IYCRbjkiDhuehEoVKjmg+xKr44+0Gevy/8Mvaye6KkhVii1t1ROaVM6qM5R4omk2 /WkittqDpKlKVLil9Mi61VganqMV6KqBg0fbuzIdQLGydIrnY56uWSCj4qo+4p1P vWahP/iMjF7pn4MHcsW2Same7BvTcvxvbjPzHAAHNUJbMgWJ7hAo+A6YXRnh/8mj k6p4H9LE/wmx0tvjJ/v2AqL9JGZwxwQR+Tg0TUXvcpU2cqIV3m3qLD1ECO7UlmD0 I2NRfgXfcAc89cPMrFIy6gAIzdfkDt8+SUct7mDOb4IzlYrB/sgryYL5xV0HnFl5 xCS8S9rZ4LzP+5yU1kslOBhV/upyz63cJF+TolqXK/FmPMU3I4W0cxDv5xe6MFWW rnJQ1eaSi/V3wkvx305/89Q+WUq3xs2PIrYtos+jAexCLqd4NhL1mehXImUcpO2d hrz3alb7ItTV1SF5viFJHCFId1CV3L3uro5kRKz3zADDCnJ1+ynOTLbabw0TzH+p sk6bgFA6U5qpw5QLadFo =qt8Q -----END PGP SIGNATURE----- --Sig_/wzicHYQ+/NYNyUSV1XMciXz--