xref: /kvm-unit-tests/s390x/stsi.c (revision c98ce6e0f823e2aaccdf6af60103a71853ad6f92)
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 <asm/page.h>
13 #include <asm/asm-offsets.h>
14 #include <asm/interrupt.h>
15 #include <smp.h>
16 #include <stsi.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 void test_fc(void)
56 {
57 	report(stsi(pagebuf, 7, 0, 0) == 3, "invalid fc");
58 	report(stsi(pagebuf, 1, 0, 1) == 3, "invalid selector 1");
59 	report(stsi(pagebuf, 1, 1, 0) == 3, "invalid selector 2");
60 	report(stsi_get_fc() >= 2, "query fc >= 2");
61 }
62 
63 static void test_3_2_2(void)
64 {
65 	int rc;
66 	/* EBCDIC for "kvm-unit" */
67 	const uint8_t vm_name[] = { 0x92, 0xa5, 0x94, 0x60, 0xa4, 0x95, 0x89,
68 				    0xa3 };
69 	const uint8_t uuid[] = { 0x0f, 0xb8, 0x4a, 0x86, 0x72, 0x7c,
70 				 0x11, 0xea, 0xbc, 0x55, 0x02, 0x42, 0xac, 0x13,
71 				 0x00, 0x03 };
72 	/* EBCDIC for "KVM/" */
73 	const uint8_t cpi_kvm[] = { 0xd2, 0xe5, 0xd4, 0x61 };
74 	const char vm_name_ext[] = "kvm-unit-test";
75 	struct sysinfo_3_2_2 *data = (void *)pagebuf;
76 
77 	report_prefix_push("3.2.2");
78 
79 	/* Is the function code available at all? */
80 	if (stsi_get_fc() < 3) {
81 		report_skip("Running under lpar, no level 3 to test.");
82 		goto out;
83 	}
84 
85 	rc = stsi(pagebuf, 3, 2, 2);
86 	report(!rc, "call");
87 
88 	/* For now we concentrate on KVM/QEMU */
89 	if (memcmp(&data->vm[0].cpi, cpi_kvm, sizeof(cpi_kvm))) {
90 		report_skip("Not running under KVM/QEMU.");
91 		goto out;
92 	}
93 
94 	report(!memcmp(data->vm[0].uuid, uuid, sizeof(uuid)), "uuid");
95 	report(data->vm[0].conf_cpus == smp_query_num_cpus(), "cpu count configured");
96 	report(data->vm[0].total_cpus ==
97 	       data->vm[0].reserved_cpus + data->vm[0].conf_cpus,
98 	       "cpu count total == conf + reserved");
99 	report(data->vm[0].standby_cpus == 0, "cpu count standby");
100 	report(!memcmp(data->vm[0].name, vm_name, sizeof(data->vm[0].name)),
101 	       "VM name == kvm-unit-test");
102 
103 	if (data->vm[0].ext_name_encoding != 2) {
104 		report_skip("Extended VM names are not UTF-8.");
105 		goto out;
106 	}
107 	report(!memcmp(data->ext_names[0], vm_name_ext, sizeof(vm_name_ext)),
108 		       "ext VM name == kvm-unit-test");
109 
110 out:
111 	report_prefix_pop();
112 }
113 
114 int main(void)
115 {
116 	report_prefix_push("stsi");
117 	test_priv();
118 	test_specs();
119 	test_fc();
120 	test_3_2_2();
121 	return report_summary();
122 }
123