1 #include <libcflat.h> 2 #include <asm/asm-offsets.h> 3 #include <asm/arch_def.h> 4 #include <asm/interrupt.h> 5 #include <asm/page.h> 6 #include <alloc_page.h> 7 #include <vmalloc.h> 8 #include <asm/facility.h> 9 #include <mmu.h> 10 #include <sclp.h> 11 #include <sie.h> 12 13 static u8 *guest; 14 static u8 *guest_instr; 15 static struct vm vm; 16 17 static void handle_validity(struct vm *vm) 18 { 19 report(0, "VALIDITY: %x", vm->sblk->ipb >> 16); 20 } 21 22 static void sie(struct vm *vm) 23 { 24 while (vm->sblk->icptcode == 0) { 25 sie64a(vm->sblk, &vm->save_area); 26 if (vm->sblk->icptcode == ICPT_VALIDITY) 27 handle_validity(vm); 28 } 29 vm->save_area.guest.grs[14] = vm->sblk->gg14; 30 vm->save_area.guest.grs[15] = vm->sblk->gg15; 31 } 32 33 static void sblk_cleanup(struct vm *vm) 34 { 35 vm->sblk->icptcode = 0; 36 } 37 38 static void test_diag(u32 instr) 39 { 40 vm.sblk->gpsw.addr = PAGE_SIZE * 2; 41 vm.sblk->gpsw.mask = 0x0000000180000000ULL; 42 43 memset(guest_instr, 0, PAGE_SIZE); 44 memcpy(guest_instr, &instr, 4); 45 sie(&vm); 46 report(vm.sblk->icptcode == ICPT_INST && 47 vm.sblk->ipa == instr >> 16 && vm.sblk->ipb == instr << 16, 48 "Intercept data"); 49 sblk_cleanup(&vm); 50 } 51 52 static struct { 53 const char *name; 54 u32 instr; 55 } tests[] = { 56 { "10", 0x83020010 }, 57 { "44", 0x83020044 }, 58 { "9c", 0x8302009c }, 59 { NULL, 0 } 60 }; 61 62 static void test_diags(void) 63 { 64 int i; 65 66 for (i = 0; tests[i].name; i++) { 67 report_prefix_push(tests[i].name); 68 test_diag(tests[i].instr); 69 report_prefix_pop(); 70 } 71 } 72 73 static void setup_guest(void) 74 { 75 setup_vm(); 76 77 /* Allocate 1MB as guest memory */ 78 guest = alloc_pages(8); 79 /* The first two pages are the lowcore */ 80 guest_instr = guest + PAGE_SIZE * 2; 81 82 vm.sblk = alloc_page(); 83 84 vm.sblk->cpuflags = CPUSTAT_ZARCH | CPUSTAT_RUNNING; 85 vm.sblk->prefix = 0; 86 /* 87 * Pageable guest with the same ASCE as the test programm, but 88 * the guest memory 0x0 is offset to start at the allocated 89 * guest pages and end after 1MB. 90 * 91 * It's not pretty but faster and easier than managing guest ASCEs. 92 */ 93 vm.sblk->mso = (u64)guest; 94 vm.sblk->msl = (u64)guest; 95 vm.sblk->ihcpu = 0xffff; 96 97 vm.sblk->crycbd = (uint64_t)alloc_page(); 98 } 99 100 int main(void) 101 { 102 report_prefix_push("sie"); 103 if (!sclp_facilities.has_sief2) { 104 report_skip("SIEF2 facility unavailable"); 105 goto done; 106 } 107 108 setup_guest(); 109 test_diags(); 110 done: 111 report_prefix_pop(); 112 return report_summary(); 113 } 114