xref: /kvm-unit-tests/s390x/stsi.c (revision a299895b7abb54e7ba6bb4108f202acbb484ac65)
1 /*
2  * Store System Information tests
3  *
4  * Copyright (c) 2019 IBM Corp
5  *
6  * Authors:
7  *  Janosch Frank <frankja@linux.ibm.com>
8  *
9  * This code is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Library General Public License version 2.
11  */
12 
13 #include <libcflat.h>
14 #include <asm/page.h>
15 #include <asm/asm-offsets.h>
16 #include <asm/interrupt.h>
17 
18 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
19 
20 static void test_specs(void)
21 {
22 	report_prefix_push("specification");
23 
24 	report_prefix_push("inv r0");
25 	expect_pgm_int();
26 	stsi(pagebuf, 0, 1 << 8, 0);
27 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
28 	report_prefix_pop();
29 
30 	report_prefix_push("inv r1");
31 	expect_pgm_int();
32 	stsi(pagebuf, 1, 0, 1 << 16);
33 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
34 	report_prefix_pop();
35 
36 	report_prefix_push("unaligned");
37 	expect_pgm_int();
38 	stsi(pagebuf + 42, 1, 1, 1);
39 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
40 	report_prefix_pop();
41 
42 	report_prefix_pop();
43 }
44 
45 static void test_priv(void)
46 {
47 	report_prefix_push("privileged");
48 	expect_pgm_int();
49 	enter_pstate();
50 	stsi(pagebuf, 0, 0, 0);
51 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
52 	report_prefix_pop();
53 }
54 
55 static inline unsigned long stsi_get_fc(void *addr)
56 {
57 	register unsigned long r0 asm("0") = 0;
58 	register unsigned long r1 asm("1") = 0;
59 	int cc;
60 
61 	asm volatile("stsi	0(%[addr])\n"
62 		     "ipm	%[cc]\n"
63 		     "srl	%[cc],28\n"
64 		     : "+d" (r0), [cc] "=d" (cc)
65 		     : "d" (r1), [addr] "a" (addr)
66 		     : "cc", "memory");
67 	assert(!cc);
68 	return r0 >> 28;
69 }
70 
71 static void test_fc(void)
72 {
73 	report(stsi(pagebuf, 7, 0, 0) == 3, "invalid fc");
74 	report(stsi(pagebuf, 1, 0, 1) == 3, "invalid selector 1");
75 	report(stsi(pagebuf, 1, 1, 0) == 3, "invalid selector 2");
76 	report(stsi_get_fc(pagebuf) >= 2, "query fc >= 2");
77 }
78 
79 int main(void)
80 {
81 	report_prefix_push("stsi");
82 	test_priv();
83 	test_specs();
84 	test_fc();
85 	return report_summary();
86 }
87