1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright IBM Corp. 2021 4 * 5 * Specification exception interception test. 6 * Checks that specification exception interceptions occur as expected when 7 * specification exception interpretation is off/on. 8 */ 9 #include <libcflat.h> 10 #include <sclp.h> 11 #include <asm/page.h> 12 #include <asm/arch_def.h> 13 #include <alloc_page.h> 14 #include <vm.h> 15 #include <sie.h> 16 #include <snippet.h> 17 18 static struct vm vm; 19 extern const char SNIPPET_NAME_START(c, spec_ex)[]; 20 extern const char SNIPPET_NAME_END(c, spec_ex)[]; 21 22 static void setup_guest(void) 23 { 24 char *guest; 25 int binary_size = SNIPPET_LEN(c, spec_ex); 26 27 setup_vm(); 28 guest = alloc_pages(8); 29 memcpy(guest, SNIPPET_NAME_START(c, spec_ex), binary_size); 30 sie_guest_create(&vm, (uint64_t) guest, HPAGE_SIZE); 31 } 32 33 static void reset_guest(void) 34 { 35 vm.sblk->gpsw = snippet_psw; 36 vm.sblk->icptcode = 0; 37 } 38 39 static void test_spec_ex_sie(void) 40 { 41 setup_guest(); 42 43 report_prefix_push("SIE spec ex interpretation"); 44 report_prefix_push("off"); 45 reset_guest(); 46 sie(&vm); 47 /* interpretation off -> initial exception must cause interception */ 48 report(vm.sblk->icptcode == ICPT_PROGI 49 && vm.sblk->iprcc == PGM_INT_CODE_SPECIFICATION 50 && vm.sblk->gpsw.addr != 0xdeadbeee, 51 "Received specification exception intercept for initial exception"); 52 report_prefix_pop(); 53 54 report_prefix_push("on"); 55 vm.sblk->ecb |= ECB_SPECI; 56 reset_guest(); 57 sie(&vm); 58 /* interpretation on -> configuration dependent if initial exception causes 59 * interception, but invalid new program PSW must 60 */ 61 report(vm.sblk->icptcode == ICPT_PROGI 62 && vm.sblk->iprcc == PGM_INT_CODE_SPECIFICATION, 63 "Received specification exception intercept"); 64 if (vm.sblk->gpsw.addr == 0xdeadbeee) 65 report_info("Interpreted initial exception, intercepted invalid program new PSW exception"); 66 else 67 report_info("Did not interpret initial exception"); 68 report_prefix_pop(); 69 report_prefix_pop(); 70 } 71 72 int main(int argc, char **argv) 73 { 74 if (!sclp_facilities.has_sief2) { 75 report_skip("SIEF2 facility unavailable"); 76 goto out; 77 } 78 79 test_spec_ex_sie(); 80 out: 81 return report_summary(); 82 } 83