1aa8794b1SJanosch Frank /* SPDX-License-Identifier: GPL-2.0-only */ 2aa8794b1SJanosch Frank /* 3aa8794b1SJanosch Frank * Tests SIE diagnose intercepts. 4aa8794b1SJanosch Frank * Mainly used as a template for SIE tests. 5aa8794b1SJanosch Frank * 6aa8794b1SJanosch Frank * Copyright 2021 IBM Corp. 7aa8794b1SJanosch Frank * 8aa8794b1SJanosch Frank * Authors: 9aa8794b1SJanosch Frank * Janosch Frank <frankja@linux.ibm.com> 10aa8794b1SJanosch Frank */ 119ec666ecSJanosch Frank #include <libcflat.h> 129ec666ecSJanosch Frank #include <asm/asm-offsets.h> 139ec666ecSJanosch Frank #include <asm/arch_def.h> 149ec666ecSJanosch Frank #include <asm/interrupt.h> 159ec666ecSJanosch Frank #include <asm/page.h> 169ec666ecSJanosch Frank #include <alloc_page.h> 179ec666ecSJanosch Frank #include <vmalloc.h> 189ec666ecSJanosch Frank #include <asm/facility.h> 199ec666ecSJanosch Frank #include <mmu.h> 209ec666ecSJanosch Frank #include <sclp.h> 219ec666ecSJanosch Frank #include <sie.h> 229ec666ecSJanosch Frank 239ec666ecSJanosch Frank static u8 *guest; 249ec666ecSJanosch Frank static u8 *guest_instr; 259ec666ecSJanosch Frank static struct vm vm; 269ec666ecSJanosch Frank 279ec666ecSJanosch Frank 289ec666ecSJanosch Frank static void sie(struct vm *vm) 299ec666ecSJanosch Frank { 309ec666ecSJanosch Frank while (vm->sblk->icptcode == 0) { 319ec666ecSJanosch Frank sie64a(vm->sblk, &vm->save_area); 32d75fac5fSJanosch Frank sie_handle_validity(vm); 339ec666ecSJanosch Frank } 349ec666ecSJanosch Frank vm->save_area.guest.grs[14] = vm->sblk->gg14; 359ec666ecSJanosch Frank vm->save_area.guest.grs[15] = vm->sblk->gg15; 369ec666ecSJanosch Frank } 379ec666ecSJanosch Frank 389ec666ecSJanosch Frank static void sblk_cleanup(struct vm *vm) 399ec666ecSJanosch Frank { 409ec666ecSJanosch Frank vm->sblk->icptcode = 0; 419ec666ecSJanosch Frank } 429ec666ecSJanosch Frank 439ec666ecSJanosch Frank static void test_diag(u32 instr) 449ec666ecSJanosch Frank { 459ec666ecSJanosch Frank vm.sblk->gpsw.addr = PAGE_SIZE * 2; 469ec666ecSJanosch Frank vm.sblk->gpsw.mask = 0x0000000180000000ULL; 479ec666ecSJanosch Frank 489ec666ecSJanosch Frank memset(guest_instr, 0, PAGE_SIZE); 499ec666ecSJanosch Frank memcpy(guest_instr, &instr, 4); 509ec666ecSJanosch Frank sie(&vm); 519ec666ecSJanosch Frank report(vm.sblk->icptcode == ICPT_INST && 529ec666ecSJanosch Frank vm.sblk->ipa == instr >> 16 && vm.sblk->ipb == instr << 16, 539ec666ecSJanosch Frank "Intercept data"); 549ec666ecSJanosch Frank sblk_cleanup(&vm); 559ec666ecSJanosch Frank } 569ec666ecSJanosch Frank 579ec666ecSJanosch Frank static struct { 589ec666ecSJanosch Frank const char *name; 599ec666ecSJanosch Frank u32 instr; 609ec666ecSJanosch Frank } tests[] = { 619ec666ecSJanosch Frank { "10", 0x83020010 }, 629ec666ecSJanosch Frank { "44", 0x83020044 }, 639ec666ecSJanosch Frank { "9c", 0x8302009c }, 649ec666ecSJanosch Frank { NULL, 0 } 659ec666ecSJanosch Frank }; 669ec666ecSJanosch Frank 679ec666ecSJanosch Frank static void test_diags(void) 689ec666ecSJanosch Frank { 699ec666ecSJanosch Frank int i; 709ec666ecSJanosch Frank 719ec666ecSJanosch Frank for (i = 0; tests[i].name; i++) { 729ec666ecSJanosch Frank report_prefix_push(tests[i].name); 739ec666ecSJanosch Frank test_diag(tests[i].instr); 749ec666ecSJanosch Frank report_prefix_pop(); 759ec666ecSJanosch Frank } 769ec666ecSJanosch Frank } 779ec666ecSJanosch Frank 789ec666ecSJanosch Frank static void setup_guest(void) 799ec666ecSJanosch Frank { 809ec666ecSJanosch Frank setup_vm(); 819ec666ecSJanosch Frank 829ec666ecSJanosch Frank /* Allocate 1MB as guest memory */ 839ec666ecSJanosch Frank guest = alloc_pages(8); 849ec666ecSJanosch Frank /* The first two pages are the lowcore */ 859ec666ecSJanosch Frank guest_instr = guest + PAGE_SIZE * 2; 869ec666ecSJanosch Frank 87*a58e5546SJanosch Frank sie_guest_create(&vm, (uint64_t)guest, HPAGE_SIZE); 889ec666ecSJanosch Frank } 899ec666ecSJanosch Frank 909ec666ecSJanosch Frank int main(void) 919ec666ecSJanosch Frank { 929ec666ecSJanosch Frank report_prefix_push("sie"); 939ec666ecSJanosch Frank if (!sclp_facilities.has_sief2) { 949ec666ecSJanosch Frank report_skip("SIEF2 facility unavailable"); 959ec666ecSJanosch Frank goto done; 969ec666ecSJanosch Frank } 979ec666ecSJanosch Frank 989ec666ecSJanosch Frank setup_guest(); 999ec666ecSJanosch Frank test_diags(); 100*a58e5546SJanosch Frank sie_guest_destroy(&vm); 101*a58e5546SJanosch Frank 1029ec666ecSJanosch Frank done: 1039ec666ecSJanosch Frank report_prefix_pop(); 1049ec666ecSJanosch Frank return report_summary(); 1059ec666ecSJanosch Frank } 106