Message ID | 20201127130629.120469-6-frankja@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | s390x: Add SIE library and simple test | expand |
On 27/11/2020 14.06, Janosch Frank wrote: > Let's check if we get the correct interception data on a few > diags. This commit is more of an addition of boilerplate code than a > real test. > > Signed-off-by: Janosch Frank <frankja@linux.ibm.com> > --- > s390x/Makefile | 1 + > s390x/sie.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ > s390x/unittests.cfg | 3 ++ > 3 files changed, 129 insertions(+) > create mode 100644 s390x/sie.c > > diff --git a/s390x/Makefile b/s390x/Makefile > index b079a26..7a95092 100644 > --- a/s390x/Makefile > +++ b/s390x/Makefile > @@ -19,6 +19,7 @@ tests += $(TEST_DIR)/smp.elf > tests += $(TEST_DIR)/sclp.elf > tests += $(TEST_DIR)/css.elf > tests += $(TEST_DIR)/uv-guest.elf > +tests += $(TEST_DIR)/sie.elf > > tests_binary = $(patsubst %.elf,%.bin,$(tests)) > ifneq ($(HOST_KEY_DOCUMENT),) > diff --git a/s390x/sie.c b/s390x/sie.c > new file mode 100644 > index 0000000..41b429a > --- /dev/null > +++ b/s390x/sie.c > @@ -0,0 +1,125 @@ > +#include <libcflat.h> > +#include <asm/asm-offsets.h> > +#include <asm/arch_def.h> > +#include <asm/interrupt.h> > +#include <asm/page.h> > +#include <alloc_page.h> > +#include <vmalloc.h> > +#include <asm/facility.h> > +#include <mmu.h> > +#include <sclp.h> > +#include <sie.h> > + > +static u8 *guest; > +static u8 *guest_instr; > +static struct vm vm; > + > +static void handle_validity(struct vm *vm) > +{ > + report(0, "VALIDITY: %x", vm->sblk->ipb >> 16); > +} > + > +static void sie(struct vm *vm) > +{ > + while (vm->sblk->icptcode == 0) { > + sie64a(vm->sblk, &vm->save_area); > + if (vm->sblk->icptcode == 32) > + handle_validity(vm); Indent with TABs, not spaces, please. > + } > + vm->save_area.guest.grs[14] = vm->sblk->gg14; > + vm->save_area.guest.grs[15] = vm->sblk->gg15; > +} > + > +static void sblk_cleanup(struct vm *vm) > +{ > + vm->sblk->icptcode = 0; > +} > + > +static void intercept_diag_10(void) > +{ > + u32 instr = 0x83020010; > + > + vm.sblk->gpsw.addr = PAGE_SIZE * 2; > + vm.sblk->gpsw.mask = 0x0000000180000000ULL; > + > + memset(guest_instr, 0, PAGE_SIZE); > + memcpy(guest_instr, &instr, 4); > + sie(&vm); > + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x100000, > + "Diag 10 intercept"); > + sblk_cleanup(&vm); > +} > + > +static void intercept_diag_44(void) > +{ > + u32 instr = 0x83020044; > + > + vm.sblk->gpsw.addr = PAGE_SIZE * 2; > + vm.sblk->gpsw.mask = 0x0000000180000000ULL; > + > + memset(guest_instr, 0, PAGE_SIZE); > + memcpy(guest_instr, &instr, 4); > + sie(&vm); > + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x440000, > + "Diag 44 intercept"); > + sblk_cleanup(&vm); > +} > + > +static void intercept_diag_9c(void) > +{ > + u32 instr = 0x8302009c; > + > + vm.sblk->gpsw.addr = PAGE_SIZE * 2; > + vm.sblk->gpsw.mask = 0x0000000180000000ULL; > + > + memset(guest_instr, 0, PAGE_SIZE); > + memcpy(guest_instr, &instr, 4); > + sie(&vm); > + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x9c0000, > + "Diag 9c intercept"); > + sblk_cleanup(&vm); > +} All three functions are pretty much the same code, except for the diag number. I think you could use a unified function for this and then just call it three times with the wanted diagnose code? Or do you plan to extend these functions later in different ways? Thomas
On Fri, 27 Nov 2020 08:06:27 -0500 Janosch Frank <frankja@linux.ibm.com> wrote: > Let's check if we get the correct interception data on a few > diags. This commit is more of an addition of boilerplate code than a > real test. > > Signed-off-by: Janosch Frank <frankja@linux.ibm.com> > --- > s390x/Makefile | 1 + > s390x/sie.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ > s390x/unittests.cfg | 3 ++ > 3 files changed, 129 insertions(+) > create mode 100644 s390x/sie.c > (...) > +static void sie(struct vm *vm) > +{ > + while (vm->sblk->icptcode == 0) { > + sie64a(vm->sblk, &vm->save_area); > + if (vm->sblk->icptcode == 32) Can you maybe add #defines for the intercept codes you're checking for? > + handle_validity(vm); > + } > + vm->save_area.guest.grs[14] = vm->sblk->gg14; > + vm->save_area.guest.grs[15] = vm->sblk->gg15; > +} > + > +static void sblk_cleanup(struct vm *vm) > +{ > + vm->sblk->icptcode = 0; > +} > + > +static void intercept_diag_10(void) > +{ > + u32 instr = 0x83020010; > + > + vm.sblk->gpsw.addr = PAGE_SIZE * 2; > + vm.sblk->gpsw.mask = 0x0000000180000000ULL; > + > + memset(guest_instr, 0, PAGE_SIZE); > + memcpy(guest_instr, &instr, 4); > + sie(&vm); > + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x100000, Again, some #defines might help here, making clear that 0x8302 means diag. (The ipb value is clear enough :) Maybe you can also assemble instr out of pre-made pieces? Or factor out some code to a common function? > + "Diag 10 intercept"); > + sblk_cleanup(&vm); > +} > + > +static void intercept_diag_44(void) > +{ > + u32 instr = 0x83020044; > + > + vm.sblk->gpsw.addr = PAGE_SIZE * 2; > + vm.sblk->gpsw.mask = 0x0000000180000000ULL; > + > + memset(guest_instr, 0, PAGE_SIZE); > + memcpy(guest_instr, &instr, 4); > + sie(&vm); > + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x440000, > + "Diag 44 intercept"); > + sblk_cleanup(&vm); > +} > + > +static void intercept_diag_9c(void) > +{ > + u32 instr = 0x8302009c; > + > + vm.sblk->gpsw.addr = PAGE_SIZE * 2; > + vm.sblk->gpsw.mask = 0x0000000180000000ULL; > + > + memset(guest_instr, 0, PAGE_SIZE); > + memcpy(guest_instr, &instr, 4); > + sie(&vm); > + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x9c0000, > + "Diag 9c intercept"); > + sblk_cleanup(&vm); > +} (...)
On 11/30/20 11:45 AM, Cornelia Huck wrote: > On Fri, 27 Nov 2020 08:06:27 -0500 > Janosch Frank <frankja@linux.ibm.com> wrote: > >> Let's check if we get the correct interception data on a few >> diags. This commit is more of an addition of boilerplate code than a >> real test. >> >> Signed-off-by: Janosch Frank <frankja@linux.ibm.com> >> --- >> s390x/Makefile | 1 + >> s390x/sie.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ >> s390x/unittests.cfg | 3 ++ >> 3 files changed, 129 insertions(+) >> create mode 100644 s390x/sie.c >> > > (...) > >> +static void sie(struct vm *vm) >> +{ >> + while (vm->sblk->icptcode == 0) { >> + sie64a(vm->sblk, &vm->save_area); >> + if (vm->sblk->icptcode == 32) > > Can you maybe add #defines for the intercept codes you're checking for? Sure ICTP_VALIDITY and ICPT_INSTRUCTION would make sense. > >> + handle_validity(vm); >> + } >> + vm->save_area.guest.grs[14] = vm->sblk->gg14; >> + vm->save_area.guest.grs[15] = vm->sblk->gg15; >> +} >> + >> +static void sblk_cleanup(struct vm *vm) >> +{ >> + vm->sblk->icptcode = 0; >> +} >> + >> +static void intercept_diag_10(void) >> +{ >> + u32 instr = 0x83020010; >> + >> + vm.sblk->gpsw.addr = PAGE_SIZE * 2; >> + vm.sblk->gpsw.mask = 0x0000000180000000ULL; >> + >> + memset(guest_instr, 0, PAGE_SIZE); >> + memcpy(guest_instr, &instr, 4); >> + sie(&vm); >> + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x100000, > > Again, some #defines might help here, making clear that 0x8302 means > diag. (The ipb value is clear enough :) Maybe you can also assemble > instr out of pre-made pieces? Or factor out some code to a common > function? Yes, a diag test function that has the code as a parameter would make this look nicer and I could also test ipa against the first 16bits of instr. > >> + "Diag 10 intercept"); >> + sblk_cleanup(&vm); >> +} >> + >> +static void intercept_diag_44(void) >> +{ >> + u32 instr = 0x83020044; >> + >> + vm.sblk->gpsw.addr = PAGE_SIZE * 2; >> + vm.sblk->gpsw.mask = 0x0000000180000000ULL; >> + >> + memset(guest_instr, 0, PAGE_SIZE); >> + memcpy(guest_instr, &instr, 4); >> + sie(&vm); >> + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x440000, >> + "Diag 44 intercept"); >> + sblk_cleanup(&vm); >> +} >> + >> +static void intercept_diag_9c(void) >> +{ >> + u32 instr = 0x8302009c; >> + >> + vm.sblk->gpsw.addr = PAGE_SIZE * 2; >> + vm.sblk->gpsw.mask = 0x0000000180000000ULL; >> + >> + memset(guest_instr, 0, PAGE_SIZE); >> + memcpy(guest_instr, &instr, 4); >> + sie(&vm); >> + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x9c0000, >> + "Diag 9c intercept"); >> + sblk_cleanup(&vm); >> +} > > (...) >
diff --git a/s390x/Makefile b/s390x/Makefile index b079a26..7a95092 100644 --- a/s390x/Makefile +++ b/s390x/Makefile @@ -19,6 +19,7 @@ tests += $(TEST_DIR)/smp.elf tests += $(TEST_DIR)/sclp.elf tests += $(TEST_DIR)/css.elf tests += $(TEST_DIR)/uv-guest.elf +tests += $(TEST_DIR)/sie.elf tests_binary = $(patsubst %.elf,%.bin,$(tests)) ifneq ($(HOST_KEY_DOCUMENT),) diff --git a/s390x/sie.c b/s390x/sie.c new file mode 100644 index 0000000..41b429a --- /dev/null +++ b/s390x/sie.c @@ -0,0 +1,125 @@ +#include <libcflat.h> +#include <asm/asm-offsets.h> +#include <asm/arch_def.h> +#include <asm/interrupt.h> +#include <asm/page.h> +#include <alloc_page.h> +#include <vmalloc.h> +#include <asm/facility.h> +#include <mmu.h> +#include <sclp.h> +#include <sie.h> + +static u8 *guest; +static u8 *guest_instr; +static struct vm vm; + +static void handle_validity(struct vm *vm) +{ + report(0, "VALIDITY: %x", vm->sblk->ipb >> 16); +} + +static void sie(struct vm *vm) +{ + while (vm->sblk->icptcode == 0) { + sie64a(vm->sblk, &vm->save_area); + if (vm->sblk->icptcode == 32) + handle_validity(vm); + } + vm->save_area.guest.grs[14] = vm->sblk->gg14; + vm->save_area.guest.grs[15] = vm->sblk->gg15; +} + +static void sblk_cleanup(struct vm *vm) +{ + vm->sblk->icptcode = 0; +} + +static void intercept_diag_10(void) +{ + u32 instr = 0x83020010; + + vm.sblk->gpsw.addr = PAGE_SIZE * 2; + vm.sblk->gpsw.mask = 0x0000000180000000ULL; + + memset(guest_instr, 0, PAGE_SIZE); + memcpy(guest_instr, &instr, 4); + sie(&vm); + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x100000, + "Diag 10 intercept"); + sblk_cleanup(&vm); +} + +static void intercept_diag_44(void) +{ + u32 instr = 0x83020044; + + vm.sblk->gpsw.addr = PAGE_SIZE * 2; + vm.sblk->gpsw.mask = 0x0000000180000000ULL; + + memset(guest_instr, 0, PAGE_SIZE); + memcpy(guest_instr, &instr, 4); + sie(&vm); + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x440000, + "Diag 44 intercept"); + sblk_cleanup(&vm); +} + +static void intercept_diag_9c(void) +{ + u32 instr = 0x8302009c; + + vm.sblk->gpsw.addr = PAGE_SIZE * 2; + vm.sblk->gpsw.mask = 0x0000000180000000ULL; + + memset(guest_instr, 0, PAGE_SIZE); + memcpy(guest_instr, &instr, 4); + sie(&vm); + report(vm.sblk->icptcode == 4 && vm.sblk->ipa == 0x8302 && vm.sblk->ipb == 0x9c0000, + "Diag 9c intercept"); + sblk_cleanup(&vm); +} + +static void setup_guest(void) +{ + setup_vm(); + + /* Allocate 1MB as guest memory */ + guest = alloc_pages(8); + /* The first two pages are the lowcore */ + guest_instr = guest + PAGE_SIZE * 2; + + vm.sblk = alloc_page(); + + vm.sblk->cpuflags = CPUSTAT_ZARCH | CPUSTAT_RUNNING; + vm.sblk->prefix = 0; + /* + * Pageable guest with the same ASCE as the test programm, but + * the guest memory 0x0 is offset to start at the allocated + * guest pages and end after 1MB. + * + * It's not pretty but faster and easier than managing guest ASCEs. + */ + vm.sblk->mso = (u64)guest; + vm.sblk->msl = (u64)guest; + vm.sblk->ihcpu = 0xffff; + + vm.sblk->crycbd = (uint64_t)alloc_page(); +} + +int main(void) +{ + report_prefix_push("sie"); + if (!sclp_facilities.has_sief2) { + report_skip("SIEF2 facility unavailable"); + goto done; + } + + setup_guest(); + intercept_diag_10(); + intercept_diag_44(); + intercept_diag_9c(); +done: + report_prefix_pop(); + return report_summary(); +} diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg index 3feb8bc..2298be6 100644 --- a/s390x/unittests.cfg +++ b/s390x/unittests.cfg @@ -96,3 +96,6 @@ smp = 2 [uv-guest] file = uv-guest.elf + +[sie] +file = sie.elf
Let's check if we get the correct interception data on a few diags. This commit is more of an addition of boilerplate code than a real test. Signed-off-by: Janosch Frank <frankja@linux.ibm.com> --- s390x/Makefile | 1 + s390x/sie.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 3 ++ 3 files changed, 129 insertions(+) create mode 100644 s390x/sie.c