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