xref: /kvm-unit-tests/s390x/stsi.c (revision 1a4529ce83922a5da6a68d3c659c51833e7d691e)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Store System Information tests
4  *
5  * Copyright (c) 2019 IBM Corp
6  *
7  * Authors:
8  *  Janosch Frank <frankja@linux.ibm.com>
9  */
10 
11 #include <libcflat.h>
12 #include <bitops.h>
13 #include <asm/page.h>
14 #include <asm/asm-offsets.h>
15 #include <asm/interrupt.h>
16 #include <smp.h>
17 #include <stsi.h>
18 
19 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
20 
test_specs(void)21 static void test_specs(void)
22 {
23 	int i;
24 	int cc;
25 
26 	report_prefix_push("specification");
27 
28 	for (i = 36; i <= 55; i++) {
29 		report_prefix_pushf("set invalid r0 bit %d", i);
30 		expect_pgm_int();
31 		stsi(pagebuf, 0, BIT(63 - i), 0);
32 		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
33 		report_prefix_pop();
34 	}
35 
36 	for (i = 32; i <= 47; i++) {
37 		report_prefix_pushf("set invalid r1 bit %d", i);
38 		expect_pgm_int();
39 		stsi(pagebuf, 1, 0, BIT(63 - i));
40 		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
41 		report_prefix_pop();
42 	}
43 
44 	for (i = 0; i < 32; i++) {
45 		report_prefix_pushf("r0 bit %d ignored", i);
46 		cc = stsi(pagebuf, 3, 2 | BIT(63 - i), 2);
47 		report(!cc, "CC = 0");
48 		report_prefix_pop();
49 	}
50 
51 	for (i = 0; i < 32; i++) {
52 		report_prefix_pushf("r1 bit %d ignored", i);
53 		cc = stsi(pagebuf, 3, 2, 2 | BIT(63 - i));
54 		report(!cc, "CC = 0");
55 		report_prefix_pop();
56 	}
57 
58 	report_prefix_push("unaligned");
59 	expect_pgm_int();
60 	stsi(pagebuf + 42, 1, 1, 1);
61 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
62 	report_prefix_pop();
63 
64 	report_prefix_pop();
65 }
66 
test_priv(void)67 static void test_priv(void)
68 {
69 	report_prefix_push("privileged");
70 	expect_pgm_int();
71 	enter_pstate();
72 	stsi(pagebuf, 0, 0, 0);
73 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
74 	report_prefix_pop();
75 }
76 
test_fc(void)77 static void test_fc(void)
78 {
79 	report(stsi(pagebuf, 7, 0, 0) == 3, "invalid fc");
80 	report(stsi(pagebuf, 1, 0, 1) == 3, "invalid selector 1");
81 	report(stsi(pagebuf, 1, 1, 0) == 3, "invalid selector 2");
82 	report(stsi_get_fc() >= 2, "query fc >= 2");
83 }
84 
test_3_2_2(void)85 static void test_3_2_2(void)
86 {
87 	int rc;
88 	/* EBCDIC for "kvm-unit" */
89 	const uint8_t vm_name[] = { 0x92, 0xa5, 0x94, 0x60, 0xa4, 0x95, 0x89,
90 				    0xa3 };
91 	const uint8_t uuid[] = { 0x0f, 0xb8, 0x4a, 0x86, 0x72, 0x7c,
92 				 0x11, 0xea, 0xbc, 0x55, 0x02, 0x42, 0xac, 0x13,
93 				 0x00, 0x03 };
94 	/* EBCDIC for "KVM/" */
95 	const uint8_t cpi_kvm[] = { 0xd2, 0xe5, 0xd4, 0x61 };
96 	const char vm_name_ext[] = "kvm-unit-test";
97 	struct sysinfo_3_2_2 *data = (void *)pagebuf;
98 
99 	report_prefix_push("3.2.2");
100 
101 	/* Is the function code available at all? */
102 	if (stsi_get_fc() < 3) {
103 		report_skip("Running under lpar, no level 3 to test.");
104 		goto out;
105 	}
106 
107 	rc = stsi(pagebuf, 3, 2, 2);
108 	report(!rc, "call");
109 
110 	/* For now we concentrate on KVM/QEMU */
111 	if (memcmp(&data->vm[0].cpi, cpi_kvm, sizeof(cpi_kvm))) {
112 		report_skip("Not running under KVM/QEMU.");
113 		goto out;
114 	}
115 
116 	report(!memcmp(data->vm[0].uuid, uuid, sizeof(uuid)), "uuid");
117 	report(data->vm[0].conf_cpus == smp_query_num_cpus(), "cpu count configured");
118 	report(data->vm[0].total_cpus ==
119 	       data->vm[0].reserved_cpus + data->vm[0].conf_cpus,
120 	       "cpu count total == conf + reserved");
121 	report(data->vm[0].standby_cpus == 0, "cpu count standby");
122 	report(!memcmp(data->vm[0].name, vm_name, sizeof(data->vm[0].name)),
123 	       "VM name == kvm-unit-test");
124 
125 	if (data->vm[0].ext_name_encoding != 2) {
126 		report_skip("Extended VM names are not UTF-8.");
127 		goto out;
128 	}
129 	report(!memcmp(data->ext_names[0], vm_name_ext, sizeof(vm_name_ext)),
130 		       "ext VM name == kvm-unit-test");
131 
132 out:
133 	report_prefix_pop();
134 }
135 
main(void)136 int main(void)
137 {
138 	report_prefix_push("stsi");
139 	test_priv();
140 	test_specs();
141 	test_fc();
142 	test_3_2_2();
143 	return report_summary();
144 }
145