xref: /kvm-unit-tests/s390x/spec_ex-sie.c (revision 49934b5af0f0fb01130d42b2a21b8ea9fc631843)
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