xref: /kvm-unit-tests/s390x/adtl-status.c (revision e3c5c3ef2524c58023073c0fadde2e8ae3c04ec6)
1db1f35d9SNico Boehr /* SPDX-License-Identifier: GPL-2.0-only */
2db1f35d9SNico Boehr /*
3db1f35d9SNico Boehr  * Tests sigp store additional status order
4db1f35d9SNico Boehr  *
5db1f35d9SNico Boehr  * Copyright IBM Corp. 2022
6db1f35d9SNico Boehr  *
7db1f35d9SNico Boehr  * Authors:
8db1f35d9SNico Boehr  *    Nico Boehr <nrb@linux.ibm.com>
9db1f35d9SNico Boehr  */
10db1f35d9SNico Boehr #include <libcflat.h>
11db1f35d9SNico Boehr #include <asm/asm-offsets.h>
12db1f35d9SNico Boehr #include <asm/interrupt.h>
13db1f35d9SNico Boehr #include <asm/facility.h>
14db1f35d9SNico Boehr #include <asm-generic/barrier.h>
15db1f35d9SNico Boehr #include <asm/sigp.h>
16db1f35d9SNico Boehr #include <asm/vector.h>
17db1f35d9SNico Boehr 
18db1f35d9SNico Boehr #include <smp.h>
19db1f35d9SNico Boehr #include <gs.h>
20db1f35d9SNico Boehr 
21db1f35d9SNico Boehr static int testflag = 0;
22db1f35d9SNico Boehr 
23db1f35d9SNico Boehr #define INVALID_CPU_ADDRESS -4711
24db1f35d9SNico Boehr 
25db1f35d9SNico Boehr struct mcesa_lc12 {
26db1f35d9SNico Boehr 	uint8_t vregs[0x200];		      /* 0x000 */
27db1f35d9SNico Boehr 	uint8_t reserved200[0x400 - 0x200];   /* 0x200 */
28db1f35d9SNico Boehr 	struct gs_cb gs_cb;                   /* 0x400 */
29db1f35d9SNico Boehr 	uint8_t reserved420[0x800 - 0x420];   /* 0x420 */
30db1f35d9SNico Boehr 	uint8_t reserved800[0x1000 - 0x800];  /* 0x800 */
31db1f35d9SNico Boehr };
32db1f35d9SNico Boehr 
33db1f35d9SNico Boehr static struct mcesa_lc12 adtl_status __attribute__((aligned(4096)));
34db1f35d9SNico Boehr 
35db1f35d9SNico Boehr static uint8_t expected_vec_contents[VEC_REGISTER_NUM][VEC_REGISTER_SIZE];
36db1f35d9SNico Boehr 
37db1f35d9SNico Boehr static struct gs_cb gs_cb;
38db1f35d9SNico Boehr static struct gs_epl gs_epl;
39db1f35d9SNico Boehr 
memisset(void * s,int c,size_t n)40db1f35d9SNico Boehr static bool memisset(void *s, int c, size_t n)
41db1f35d9SNico Boehr {
42db1f35d9SNico Boehr 	uint8_t *p = s;
43db1f35d9SNico Boehr 	size_t i;
44db1f35d9SNico Boehr 
45db1f35d9SNico Boehr 	for (i = 0; i < n; i++) {
46db1f35d9SNico Boehr 		if (p[i] != c)
47db1f35d9SNico Boehr 			return false;
48db1f35d9SNico Boehr 	}
49db1f35d9SNico Boehr 
50db1f35d9SNico Boehr 	return true;
51db1f35d9SNico Boehr }
52db1f35d9SNico Boehr 
wait_for_flag(void)53db1f35d9SNico Boehr static void wait_for_flag(void)
54db1f35d9SNico Boehr {
55db1f35d9SNico Boehr 	while (!testflag)
56db1f35d9SNico Boehr 		mb();
57db1f35d9SNico Boehr }
58db1f35d9SNico Boehr 
set_flag(int val)59db1f35d9SNico Boehr static void set_flag(int val)
60db1f35d9SNico Boehr {
61db1f35d9SNico Boehr 	mb();
62db1f35d9SNico Boehr 	testflag = val;
63db1f35d9SNico Boehr 	mb();
64db1f35d9SNico Boehr }
65db1f35d9SNico Boehr 
test_func(void)66db1f35d9SNico Boehr static void test_func(void)
67db1f35d9SNico Boehr {
68db1f35d9SNico Boehr 	set_flag(1);
69db1f35d9SNico Boehr }
70db1f35d9SNico Boehr 
have_adtl_status(void)71db1f35d9SNico Boehr static bool have_adtl_status(void)
72db1f35d9SNico Boehr {
73db1f35d9SNico Boehr 	return test_facility(133) || test_facility(129);
74db1f35d9SNico Boehr }
75db1f35d9SNico Boehr 
test_store_adtl_status(void)76db1f35d9SNico Boehr static void test_store_adtl_status(void)
77db1f35d9SNico Boehr {
78db1f35d9SNico Boehr 	uint32_t status = -1;
79db1f35d9SNico Boehr 	int cc;
80db1f35d9SNico Boehr 
81db1f35d9SNico Boehr 	report_prefix_push("store additional status");
82db1f35d9SNico Boehr 
83db1f35d9SNico Boehr 	if (!have_adtl_status()) {
84db1f35d9SNico Boehr 		report_skip("no guarded-storage or vector facility installed");
85db1f35d9SNico Boehr 		goto out;
86db1f35d9SNico Boehr 	}
87db1f35d9SNico Boehr 
88db1f35d9SNico Boehr 	memset(&adtl_status, 0xff, sizeof(adtl_status));
89db1f35d9SNico Boehr 
90db1f35d9SNico Boehr 	report_prefix_push("running");
91db1f35d9SNico Boehr 	smp_cpu_restart(1);
92db1f35d9SNico Boehr 
93db1f35d9SNico Boehr 	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
94db1f35d9SNico Boehr 		  (unsigned long)&adtl_status, &status);
95db1f35d9SNico Boehr 
96db1f35d9SNico Boehr 	report(cc == 1, "CC = 1");
97db1f35d9SNico Boehr 	report(status == SIGP_STATUS_INCORRECT_STATE, "status = INCORRECT_STATE");
98db1f35d9SNico Boehr 	report(memisset(&adtl_status, 0xff, sizeof(adtl_status)),
99db1f35d9SNico Boehr 	       "additional status not touched");
100db1f35d9SNico Boehr 
101db1f35d9SNico Boehr 	report_prefix_pop();
102db1f35d9SNico Boehr 
103db1f35d9SNico Boehr 	report_prefix_push("invalid CPU address");
104db1f35d9SNico Boehr 
105db1f35d9SNico Boehr 	cc = sigp(INVALID_CPU_ADDRESS, SIGP_STORE_ADDITIONAL_STATUS,
106db1f35d9SNico Boehr 		  (unsigned long)&adtl_status, &status);
107db1f35d9SNico Boehr 	report(cc == 3, "CC = 3");
108db1f35d9SNico Boehr 	report(memisset(&adtl_status, 0xff, sizeof(adtl_status)),
109db1f35d9SNico Boehr 	       "additional status not touched");
110db1f35d9SNico Boehr 
111db1f35d9SNico Boehr 	report_prefix_pop();
112db1f35d9SNico Boehr 
113db1f35d9SNico Boehr 	report_prefix_push("unaligned");
114db1f35d9SNico Boehr 	smp_cpu_stop(1);
115db1f35d9SNico Boehr 
116db1f35d9SNico Boehr 	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
117db1f35d9SNico Boehr 		  (unsigned long)&adtl_status + 256, &status);
118db1f35d9SNico Boehr 	report(cc == 1, "CC = 1");
119db1f35d9SNico Boehr 	report(status == SIGP_STATUS_INVALID_PARAMETER, "status = INVALID_PARAMETER");
120db1f35d9SNico Boehr 	report(memisset(&adtl_status, 0xff, sizeof(adtl_status)),
121db1f35d9SNico Boehr 	       "additional status not touched");
122db1f35d9SNico Boehr 
123db1f35d9SNico Boehr 	report_prefix_pop();
124db1f35d9SNico Boehr 
125db1f35d9SNico Boehr out:
126db1f35d9SNico Boehr 	report_prefix_pop();
127db1f35d9SNico Boehr }
128db1f35d9SNico Boehr 
test_store_adtl_status_unavail(void)129db1f35d9SNico Boehr static void test_store_adtl_status_unavail(void)
130db1f35d9SNico Boehr {
131db1f35d9SNico Boehr 	uint32_t status = 0;
132db1f35d9SNico Boehr 	int cc;
133db1f35d9SNico Boehr 
134db1f35d9SNico Boehr 	report_prefix_push("store additional status unavailable");
135db1f35d9SNico Boehr 
136db1f35d9SNico Boehr 	if (have_adtl_status()) {
137db1f35d9SNico Boehr 		report_skip("guarded-storage or vector facility installed");
138db1f35d9SNico Boehr 		goto out;
139db1f35d9SNico Boehr 	}
140db1f35d9SNico Boehr 
141db1f35d9SNico Boehr 	report_prefix_push("not accepted");
142db1f35d9SNico Boehr 	smp_cpu_stop(1);
143db1f35d9SNico Boehr 
144db1f35d9SNico Boehr 	memset(&adtl_status, 0xff, sizeof(adtl_status));
145db1f35d9SNico Boehr 
146db1f35d9SNico Boehr 	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
147db1f35d9SNico Boehr 		  (unsigned long)&adtl_status, &status);
148db1f35d9SNico Boehr 
149db1f35d9SNico Boehr 	report(cc == 1, "CC = 1");
150db1f35d9SNico Boehr 	report(status == SIGP_STATUS_INVALID_ORDER,
151db1f35d9SNico Boehr 	       "status = INVALID_ORDER");
152db1f35d9SNico Boehr 	report(memisset(&adtl_status, 0xff, sizeof(adtl_status)),
153db1f35d9SNico Boehr 	       "additional status not touched");
154db1f35d9SNico Boehr 
155db1f35d9SNico Boehr 	report_prefix_pop();
156db1f35d9SNico Boehr 
157db1f35d9SNico Boehr out:
158db1f35d9SNico Boehr 	report_prefix_pop();
159db1f35d9SNico Boehr }
160db1f35d9SNico Boehr 
restart_write_vector(void)161db1f35d9SNico Boehr static void restart_write_vector(void)
162db1f35d9SNico Boehr {
163db1f35d9SNico Boehr 	uint8_t *vec_reg;
164db1f35d9SNico Boehr 	/* vlm handles at most 16 registers at a time */
165db1f35d9SNico Boehr 	uint8_t *vec_reg_16_31 = &expected_vec_contents[16][0];
166db1f35d9SNico Boehr 	uint64_t cr0, cr0_mask = ~BIT_ULL(CTL0_VECTOR);
167db1f35d9SNico Boehr 	int i;
168db1f35d9SNico Boehr 
169db1f35d9SNico Boehr 	for (i = 0; i < VEC_REGISTER_NUM; i++) {
170db1f35d9SNico Boehr 		vec_reg = &expected_vec_contents[i][0];
171db1f35d9SNico Boehr 		/* i+1 to avoid zero content */
172db1f35d9SNico Boehr 		memset(vec_reg, i + 1, VEC_REGISTER_SIZE);
173db1f35d9SNico Boehr 	}
174db1f35d9SNico Boehr 
175db1f35d9SNico Boehr 	ctl_set_bit(0, CTL0_VECTOR);
176db1f35d9SNico Boehr 
177db1f35d9SNico Boehr 	asm volatile (
178db1f35d9SNico Boehr 		"	.machine z13\n"
179db1f35d9SNico Boehr 		/* load vector registers */
180db1f35d9SNico Boehr 		"	vlm 0,15, %[vec_reg_0_15]\n"
181db1f35d9SNico Boehr 		"	vlm 16,31, %[vec_reg_16_31]\n"
182db1f35d9SNico Boehr 		/* turn off vector instructions */
183db1f35d9SNico Boehr 		"	stctg 0,0, %[cr0]\n"
184db1f35d9SNico Boehr 		"	ng %[cr0_mask], %[cr0]\n"
185db1f35d9SNico Boehr 		"	stg %[cr0_mask], %[cr0]\n"
186db1f35d9SNico Boehr 		"	lctlg 0,0, %[cr0]\n"
187db1f35d9SNico Boehr 		/* inform CPU 0 we are done by setting testflag to 1 */
188db1f35d9SNico Boehr 		"	mvhi %[testflag], 1\n"
189db1f35d9SNico Boehr 		/*
190db1f35d9SNico Boehr 		 * infinite loop. function epilogue will restore floating point
191db1f35d9SNico Boehr 		 * registers and hence destroy vector register contents
192db1f35d9SNico Boehr 		 */
193db1f35d9SNico Boehr 		"0:	j 0\n"
194db1f35d9SNico Boehr 		: [cr0_mask] "+&d"(cr0_mask)
195db1f35d9SNico Boehr 		: [vec_reg_0_15] "Q"(expected_vec_contents),
196db1f35d9SNico Boehr 		  [vec_reg_16_31] "Q"(*vec_reg_16_31),
197db1f35d9SNico Boehr 		  [cr0] "Q"(cr0),
198db1f35d9SNico Boehr 		  [testflag] "T"(testflag)
199db1f35d9SNico Boehr 		: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
200db1f35d9SNico Boehr 		  "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18",
201db1f35d9SNico Boehr 		  "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27",
202db1f35d9SNico Boehr 		  "v28", "v29", "v30", "v31", "cc", "memory"
203db1f35d9SNico Boehr 	);
204db1f35d9SNico Boehr }
205db1f35d9SNico Boehr 
cpu_write_magic_to_vector_regs(uint16_t cpu_idx)206db1f35d9SNico Boehr static void cpu_write_magic_to_vector_regs(uint16_t cpu_idx)
207db1f35d9SNico Boehr {
208db1f35d9SNico Boehr 	smp_cpu_stop(cpu_idx);
209db1f35d9SNico Boehr 
210db1f35d9SNico Boehr 	set_flag(0);
211db1f35d9SNico Boehr 
212*f514b4f7SClaudio Imbrenda 	smp_cpu_start(cpu_idx, PSW_WITH_CUR_MASK(restart_write_vector));
213db1f35d9SNico Boehr 
214db1f35d9SNico Boehr 	wait_for_flag();
215db1f35d9SNico Boehr }
216db1f35d9SNico Boehr 
adtl_status_check_unmodified_fields_for_lc(unsigned long lc)217db1f35d9SNico Boehr static int adtl_status_check_unmodified_fields_for_lc(unsigned long lc)
218db1f35d9SNico Boehr {
219db1f35d9SNico Boehr 	assert (!lc || (lc >= 10 && lc <= 12));
220db1f35d9SNico Boehr 
221db1f35d9SNico Boehr 	if (lc <= 10 && !memisset(&adtl_status.gs_cb, 0xff, sizeof(adtl_status.gs_cb)))
222db1f35d9SNico Boehr 		return false;
223db1f35d9SNico Boehr 
224db1f35d9SNico Boehr 	if (!memisset(adtl_status.reserved200, 0xff, sizeof(adtl_status.reserved200)))
225db1f35d9SNico Boehr 		return false;
226db1f35d9SNico Boehr 
227db1f35d9SNico Boehr 	if (!memisset(adtl_status.reserved420, 0xff, sizeof(adtl_status.reserved420)))
228db1f35d9SNico Boehr 		return false;
229db1f35d9SNico Boehr 
230db1f35d9SNico Boehr 	if (!memisset(adtl_status.reserved800, 0xff, sizeof(adtl_status.reserved800)))
231db1f35d9SNico Boehr 		return false;
232db1f35d9SNico Boehr 
233db1f35d9SNico Boehr 	return true;
234db1f35d9SNico Boehr }
235db1f35d9SNico Boehr 
__store_adtl_status_vector_lc(unsigned long lc)236db1f35d9SNico Boehr static void __store_adtl_status_vector_lc(unsigned long lc)
237db1f35d9SNico Boehr {
238db1f35d9SNico Boehr 	uint32_t status = -1;
239db1f35d9SNico Boehr 	int cc;
240db1f35d9SNico Boehr 
241db1f35d9SNico Boehr 	report_prefix_pushf("LC %lu", lc);
242db1f35d9SNico Boehr 
243db1f35d9SNico Boehr 	if (!test_facility(133) && lc) {
244db1f35d9SNico Boehr 		report_skip("not supported, no guarded-storage facility");
245db1f35d9SNico Boehr 		goto out;
246db1f35d9SNico Boehr 	}
247db1f35d9SNico Boehr 
248db1f35d9SNico Boehr 	cpu_write_magic_to_vector_regs(1);
249db1f35d9SNico Boehr 	smp_cpu_stop(1);
250db1f35d9SNico Boehr 
251db1f35d9SNico Boehr 	memset(&adtl_status, 0xff, sizeof(adtl_status));
252db1f35d9SNico Boehr 
253db1f35d9SNico Boehr 	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
254db1f35d9SNico Boehr 		  (unsigned long)&adtl_status | lc, &status);
255db1f35d9SNico Boehr 	report(!cc, "CC = 0");
256db1f35d9SNico Boehr 
257db1f35d9SNico Boehr 	report(!memcmp(adtl_status.vregs,
258db1f35d9SNico Boehr 		       expected_vec_contents, sizeof(expected_vec_contents)),
259db1f35d9SNico Boehr 	       "additional status contents match");
260db1f35d9SNico Boehr 
261db1f35d9SNico Boehr 	report(adtl_status_check_unmodified_fields_for_lc(lc),
262db1f35d9SNico Boehr 	       "no write outside expected fields");
263db1f35d9SNico Boehr 
264db1f35d9SNico Boehr 	/*
265db1f35d9SNico Boehr 	 * To avoid the floating point/vector registers being cleaned up, we
266db1f35d9SNico Boehr 	 * stopped CPU1 right in the middle of a function. Hence the cleanup of
267db1f35d9SNico Boehr 	 * the function didn't run yet and the stackpointer is messed up.
268db1f35d9SNico Boehr 	 * Destroy and re-initalize the CPU to fix that.
269db1f35d9SNico Boehr 	 */
270db1f35d9SNico Boehr 	smp_cpu_destroy(1);
271*f514b4f7SClaudio Imbrenda 	smp_cpu_setup(1, PSW_WITH_CUR_MASK(test_func));
272db1f35d9SNico Boehr 
273db1f35d9SNico Boehr out:
274db1f35d9SNico Boehr 	report_prefix_pop();
275db1f35d9SNico Boehr }
276db1f35d9SNico Boehr 
test_store_adtl_status_vector(void)277db1f35d9SNico Boehr static void test_store_adtl_status_vector(void)
278db1f35d9SNico Boehr {
279db1f35d9SNico Boehr 	report_prefix_push("store additional status vector");
280db1f35d9SNico Boehr 
281db1f35d9SNico Boehr 	if (!test_facility(129)) {
282db1f35d9SNico Boehr 		report_skip("vector facility not installed");
283db1f35d9SNico Boehr 		goto out;
284db1f35d9SNico Boehr 	}
285db1f35d9SNico Boehr 
286db1f35d9SNico Boehr 	__store_adtl_status_vector_lc(0);
287db1f35d9SNico Boehr 	__store_adtl_status_vector_lc(10);
288db1f35d9SNico Boehr 	__store_adtl_status_vector_lc(11);
289db1f35d9SNico Boehr 	__store_adtl_status_vector_lc(12);
290db1f35d9SNico Boehr 
291db1f35d9SNico Boehr out:
292db1f35d9SNico Boehr 	report_prefix_pop();
293db1f35d9SNico Boehr }
294db1f35d9SNico Boehr 
restart_write_gs_regs(void)295db1f35d9SNico Boehr static void restart_write_gs_regs(void)
296db1f35d9SNico Boehr {
297db1f35d9SNico Boehr 	const unsigned long gs_area = 0x2000000;
298db1f35d9SNico Boehr 	const unsigned long gsc = 25; /* align = 32 M, section size = 512K */
299db1f35d9SNico Boehr 
300db1f35d9SNico Boehr 	ctl_set_bit(2, CTL2_GUARDED_STORAGE);
301db1f35d9SNico Boehr 
302db1f35d9SNico Boehr 	gs_cb.gsd = gs_area | gsc;
303db1f35d9SNico Boehr 	gs_cb.gssm = 0xfeedc0ffe;
304db1f35d9SNico Boehr 	gs_cb.gs_epl_a = (uint64_t) &gs_epl;
305db1f35d9SNico Boehr 
306db1f35d9SNico Boehr 	load_gs_cb(&gs_cb);
307db1f35d9SNico Boehr 
308db1f35d9SNico Boehr 	set_flag(1);
309db1f35d9SNico Boehr 
310db1f35d9SNico Boehr 	ctl_clear_bit(2, CTL2_GUARDED_STORAGE);
311db1f35d9SNico Boehr 
312db1f35d9SNico Boehr 	/*
313db1f35d9SNico Boehr 	 * Safe to return here. r14 will point to the endless loop in
314db1f35d9SNico Boehr 	 * smp_cpu_setup_state.
315db1f35d9SNico Boehr 	 */
316db1f35d9SNico Boehr }
317db1f35d9SNico Boehr 
cpu_write_to_gs_regs(uint16_t cpu_idx)318db1f35d9SNico Boehr static void cpu_write_to_gs_regs(uint16_t cpu_idx)
319db1f35d9SNico Boehr {
320db1f35d9SNico Boehr 	smp_cpu_stop(cpu_idx);
321db1f35d9SNico Boehr 
322db1f35d9SNico Boehr 	set_flag(0);
323db1f35d9SNico Boehr 
324*f514b4f7SClaudio Imbrenda 	smp_cpu_start(cpu_idx, PSW_WITH_CUR_MASK(restart_write_gs_regs));
325db1f35d9SNico Boehr 
326db1f35d9SNico Boehr 	wait_for_flag();
327db1f35d9SNico Boehr }
328db1f35d9SNico Boehr 
__store_adtl_status_gs(unsigned long lc)329db1f35d9SNico Boehr static void __store_adtl_status_gs(unsigned long lc)
330db1f35d9SNico Boehr {
331db1f35d9SNico Boehr 	uint32_t status = 0;
332db1f35d9SNico Boehr 	int cc;
333db1f35d9SNico Boehr 
334db1f35d9SNico Boehr 	report_prefix_pushf("LC %lu", lc);
335db1f35d9SNico Boehr 
336db1f35d9SNico Boehr 	cpu_write_to_gs_regs(1);
337db1f35d9SNico Boehr 	smp_cpu_stop(1);
338db1f35d9SNico Boehr 
339db1f35d9SNico Boehr 	memset(&adtl_status, 0xff, sizeof(adtl_status));
340db1f35d9SNico Boehr 
341db1f35d9SNico Boehr 	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
342db1f35d9SNico Boehr 		  (unsigned long)&adtl_status | lc, &status);
343db1f35d9SNico Boehr 	report(!cc, "CC = 0");
344db1f35d9SNico Boehr 
345db1f35d9SNico Boehr 	report(!memcmp(&adtl_status.gs_cb, &gs_cb, sizeof(gs_cb)),
346db1f35d9SNico Boehr 	       "additional status contents match");
347db1f35d9SNico Boehr 
348db1f35d9SNico Boehr 	report(adtl_status_check_unmodified_fields_for_lc(lc),
349db1f35d9SNico Boehr 	       "no write outside expected fields");
350db1f35d9SNico Boehr 
351db1f35d9SNico Boehr 	report_prefix_pop();
352db1f35d9SNico Boehr }
353db1f35d9SNico Boehr 
test_store_adtl_status_gs(void)354db1f35d9SNico Boehr static void test_store_adtl_status_gs(void)
355db1f35d9SNico Boehr {
356db1f35d9SNico Boehr 	report_prefix_push("store additional status guarded-storage");
357db1f35d9SNico Boehr 
358db1f35d9SNico Boehr 	if (!test_facility(133)) {
359db1f35d9SNico Boehr 		report_skip("guarded-storage facility not installed");
360db1f35d9SNico Boehr 		goto out;
361db1f35d9SNico Boehr 	}
362db1f35d9SNico Boehr 
363db1f35d9SNico Boehr 	__store_adtl_status_gs(11);
364db1f35d9SNico Boehr 	__store_adtl_status_gs(12);
365db1f35d9SNico Boehr 
366db1f35d9SNico Boehr out:
367db1f35d9SNico Boehr 	report_prefix_pop();
368db1f35d9SNico Boehr }
369db1f35d9SNico Boehr 
main(void)370db1f35d9SNico Boehr int main(void)
371db1f35d9SNico Boehr {
372db1f35d9SNico Boehr 	report_prefix_push("adtl_status");
373db1f35d9SNico Boehr 
374db1f35d9SNico Boehr 	if (smp_query_num_cpus() == 1) {
375db1f35d9SNico Boehr 		report_skip("need at least 2 cpus for this test");
376db1f35d9SNico Boehr 		goto done;
377db1f35d9SNico Boehr 	}
378db1f35d9SNico Boehr 
379db1f35d9SNico Boehr 	/* Setting up the cpu to give it a stack and lowcore */
380*f514b4f7SClaudio Imbrenda 	smp_cpu_setup(1, PSW_WITH_CUR_MASK(test_func));
381db1f35d9SNico Boehr 	smp_cpu_stop(1);
382db1f35d9SNico Boehr 
383db1f35d9SNico Boehr 	test_store_adtl_status_unavail();
384db1f35d9SNico Boehr 	test_store_adtl_status_vector();
385db1f35d9SNico Boehr 	test_store_adtl_status_gs();
386db1f35d9SNico Boehr 	test_store_adtl_status();
387db1f35d9SNico Boehr 	smp_cpu_destroy(1);
388db1f35d9SNico Boehr 
389db1f35d9SNico Boehr done:
390db1f35d9SNico Boehr 	report_prefix_pop();
391db1f35d9SNico Boehr 	return report_summary();
392db1f35d9SNico Boehr }
393