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