1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Service Call tests
4 *
5 * Copyright (c) 2020 IBM Corp
6 *
7 * Authors:
8 * Claudio Imbrenda <imbrenda@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 <sclp.h>
16
17 #define PGM_NONE 1
18 #define PGM_BIT_SPEC (1ULL << PGM_INT_CODE_SPECIFICATION)
19 #define PGM_BIT_ADDR (1ULL << PGM_INT_CODE_ADDRESSING)
20 #define PGM_BIT_PRIV (1ULL << PGM_INT_CODE_PRIVILEGED_OPERATION)
21 #define MKPTR(x) ((void *)(uint64_t)(x))
22
23 #define LC_SIZE (2 * PAGE_SIZE)
24
25 static uint8_t pagebuf[LC_SIZE] __attribute__((aligned(LC_SIZE))); /* scratch pages used for some tests */
26 static uint8_t prefix_buf[LC_SIZE] __attribute__((aligned(LC_SIZE))); /* temporary lowcore for test_sccb_prefix */
27 /* SCCB template to be used */
28 static union {
29 uint8_t raw[PAGE_SIZE];
30 SCCBHeader header;
31 WriteEventData data;
32 } sccb_template;
33 static uint32_t valid_code; /* valid command code for READ SCP INFO */
34
35 /*
36 * Perform one service call, handling exceptions and interrupts.
37 */
sclp_service_call_test(unsigned int command,void * sccb)38 static int sclp_service_call_test(unsigned int command, void *sccb)
39 {
40 int cc;
41
42 sclp_mark_busy();
43 sclp_setup_int();
44 cc = servc(command, __pa(sccb));
45 if (lowcore.pgm_int_code) {
46 sclp_handle_ext();
47 return 0;
48 }
49 if (!cc)
50 sclp_wait_busy();
51 return cc;
52 }
53
54 /*
55 * Perform one test at the given address, optionally using the SCCB template,
56 * checking for the expected program interrupts and return codes.
57 *
58 * The parameter buf_len indicates the number of bytes of the template that
59 * should be copied to the test address, and should be 0 when the test
60 * address is invalid, in which case nothing is copied.
61 *
62 * The template is used to simplify tests where the same buffer content is
63 * used many times in a row, at different addresses.
64 *
65 * Returns true in case of success or false in case of failure
66 */
test_one_sccb(uint32_t cmd,uint8_t * addr,uint16_t buf_len,uint64_t exp_pgm,uint16_t exp_rc)67 static bool test_one_sccb(uint32_t cmd, uint8_t *addr, uint16_t buf_len, uint64_t exp_pgm, uint16_t exp_rc)
68 {
69 SCCBHeader *h = (SCCBHeader *)addr;
70 int res, pgm;
71
72 /* Copy the template to the test address if needed */
73 if (buf_len)
74 memcpy(addr, sccb_template.raw, buf_len);
75 if (exp_pgm != PGM_NONE)
76 expect_pgm_int();
77 /* perform the actual call */
78 res = sclp_service_call_test(cmd, h);
79 if (res) {
80 report_info("SCLP not ready (command %#x, address %p, cc %d)", cmd, addr, res);
81 return false;
82 }
83 pgm = clear_pgm_int();
84 /* Check if the program exception was one of the expected ones */
85 if (!((1ULL << pgm) & exp_pgm)) {
86 report_info("First failure at addr %p, buf_len %d, cmd %#x, pgm code %d",
87 addr, buf_len, cmd, pgm);
88 return false;
89 }
90 /* Check if the response code is the one expected */
91 if (exp_rc && exp_rc != h->response_code) {
92 report_info("First failure at addr %p, buf_len %d, cmd %#x, resp code %#x",
93 addr, buf_len, cmd, h->response_code);
94 return false;
95 }
96 return true;
97 }
98
99 /*
100 * Wrapper for test_one_sccb to be used when the template should not be
101 * copied and the memory address should not be touched.
102 */
test_one_ro(uint32_t cmd,uint8_t * addr,uint64_t exp_pgm,uint16_t exp_rc)103 static bool test_one_ro(uint32_t cmd, uint8_t *addr, uint64_t exp_pgm, uint16_t exp_rc)
104 {
105 return test_one_sccb(cmd, addr, 0, exp_pgm, exp_rc);
106 }
107
108 /*
109 * Wrapper for test_one_sccb to set up a simple SCCB template.
110 *
111 * The parameter sccb_len indicates the value that will be saved in the SCCB
112 * length field of the SCCB, buf_len indicates the number of bytes of
113 * template that need to be copied to the actual test address. In many cases
114 * it's enough to clear/copy the first 8 bytes of the buffer, while the SCCB
115 * itself can be larger.
116 *
117 * Returns true in case of success or false in case of failure
118 */
test_one_simple(uint32_t cmd,uint8_t * addr,uint16_t sccb_len,uint16_t buf_len,uint64_t exp_pgm,uint16_t exp_rc)119 static bool test_one_simple(uint32_t cmd, uint8_t *addr, uint16_t sccb_len,
120 uint16_t buf_len, uint64_t exp_pgm, uint16_t exp_rc)
121 {
122 memset(sccb_template.raw, 0, sizeof(sccb_template.raw));
123 sccb_template.header.length = sccb_len;
124 return test_one_sccb(cmd, addr, buf_len, exp_pgm, exp_rc);
125 }
126
127 /*
128 * Test SCCB lengths < 8.
129 */
test_sccb_too_short(void)130 static void test_sccb_too_short(void)
131 {
132 int len;
133
134 for (len = 0; len < 8; len++)
135 if (!test_one_simple(valid_code, pagebuf, len, 8, PGM_BIT_SPEC, 0))
136 break;
137
138 report(len == 8, "SCCB too short");
139 }
140
141 /*
142 * Test SCCBs that are not 64-bit aligned.
143 */
test_sccb_unaligned(void)144 static void test_sccb_unaligned(void)
145 {
146 int offset;
147
148 for (offset = 1; offset < 8; offset++)
149 if (!test_one_simple(valid_code, offset + pagebuf, 8, 8, PGM_BIT_SPEC, 0))
150 break;
151 report(offset == 8, "SCCB unaligned");
152 }
153
154 /*
155 * Test SCCBs whose address is in the lowcore or prefix area.
156 */
test_sccb_prefix(void)157 static void test_sccb_prefix(void)
158 {
159 uint8_t scratch[LC_SIZE];
160 uint32_t prefix, new_prefix;
161 int offset;
162
163 /*
164 * copy the current lowcore to the future new location, otherwise we
165 * will not have a valid lowcore after setting the new prefix.
166 */
167 memcpy(prefix_buf, 0, LC_SIZE);
168 /* save the current prefix (it's probably going to be 0) */
169 prefix = get_prefix();
170 /*
171 * save the current content of absolute pages 0 and 1, so we can
172 * restore them after we trash them later on
173 */
174 memcpy(scratch, (void *)(intptr_t)prefix, LC_SIZE);
175 /* set the new prefix to prefix_buf */
176 new_prefix = (uint32_t)(intptr_t)prefix_buf;
177 set_prefix(new_prefix);
178
179 /*
180 * testing with SCCB addresses in the lowcore; since we can't
181 * actually trash the lowcore (unsurprisingly, things break if we
182 * do), this will be a read-only test.
183 */
184 for (offset = 0; offset < LC_SIZE; offset += 8)
185 if (!test_one_ro(valid_code, MKPTR(offset), PGM_BIT_SPEC, 0))
186 break;
187 report(offset == LC_SIZE, "SCCB low pages");
188
189 /*
190 * the SCLP should not even touch the memory, but we will write the
191 * SCCBs all over the two pages starting at absolute address 0, thus
192 * trashing them; we will need to restore them later.
193 */
194 for (offset = 0; offset < LC_SIZE; offset += 8)
195 if (!test_one_simple(valid_code, MKPTR(new_prefix + offset), 8, 8, PGM_BIT_SPEC, 0))
196 break;
197 report(offset == LC_SIZE, "SCCB prefix pages");
198
199 /* restore the previous contents of absolute pages 0 and 1 */
200 memcpy(prefix_buf, 0, LC_SIZE);
201 /* restore the prefix to the original value */
202 set_prefix(prefix);
203 }
204
205 /*
206 * Test SCCBs that are above 2GB. If outside of memory, an addressing
207 * exception is also allowed.
208 */
test_sccb_high(void)209 static void test_sccb_high(void)
210 {
211 SCCBHeader *h = (SCCBHeader *)pagebuf;
212 uintptr_t a[33 * 4 * 2 + 2]; /* for the list of addresses to test */
213
214 uint64_t maxram;
215 int i, pgm, len = 0;
216
217 h->length = 8;
218 /* addresses with 1 bit set in the first 33 bits */
219 for (i = 0; i < 33; i++)
220 a[len++] = 1UL << (i + 31);
221 /* addresses with 2 consecutive bits set in the first 33 bits */
222 for (i = 0; i < 33; i++)
223 a[len++] = 3UL << (i + 31);
224 /* addresses with all bits set in bits 0..N */
225 for (i = 0; i < 33; i++)
226 a[len++] = 0xffffffff80000000UL << i;
227 /* addresses with all bits set in bits N..33 */
228 a[len++] = 0x80000000;
229 for (i = 1; i < 33; i++, len++)
230 a[len] = a[len - 1] | (1UL << (i + 31));
231 /* all the addresses above, but adding the offset of a valid buffer */
232 for (i = 0; i < len; i++)
233 a[len + i] = a[i] + (intptr_t)h;
234 len += i;
235 /* two more hand-crafted addresses */
236 a[len++] = 0xdeadbeef00000000;
237 a[len++] = 0xdeaddeadbeef0000;
238
239 maxram = get_ram_size();
240 for (i = 0; i < len; i++) {
241 pgm = PGM_BIT_SPEC | (a[i] >= maxram ? PGM_BIT_ADDR : 0);
242 if (!test_one_ro(valid_code, (void *)a[i], pgm, 0))
243 break;
244 }
245 report(i == len, "SCCB high addresses");
246 }
247
248 /*
249 * Test invalid commands, both invalid command detail codes and valid
250 * ones with invalid command class code.
251 */
test_inval(void)252 static void test_inval(void)
253 {
254 const uint16_t res = SCLP_RC_INVALID_SCLP_COMMAND;
255 uint32_t cmd;
256 int i;
257
258 report_prefix_push("Invalid command");
259 for (i = 0; i < 65536; i++) {
260 cmd = 0xdead0000 | i;
261 if (!test_one_simple(cmd, pagebuf, PAGE_SIZE, PAGE_SIZE, PGM_NONE, res))
262 break;
263 }
264 report(i == 65536, "Command detail code");
265
266 for (i = 0; i < 256; i++) {
267 cmd = (valid_code & ~0xff) | i;
268 if (cmd == valid_code)
269 continue;
270 if (!test_one_simple(cmd, pagebuf, PAGE_SIZE, PAGE_SIZE, PGM_NONE, res))
271 break;
272 }
273 report(i == 256, "Command class code");
274 report_prefix_pop();
275 }
276
277
278 /*
279 * Test short SCCBs (but larger than 8).
280 */
test_short(void)281 static void test_short(void)
282 {
283 const uint16_t res = SCLP_RC_INSUFFICIENT_SCCB_LENGTH;
284 int len;
285
286 for (len = 8; len < 144; len++)
287 if (!test_one_simple(valid_code, pagebuf, len, len, PGM_NONE, res))
288 break;
289 report(len == 144, "Insufficient SCCB length (Read SCP info)");
290
291 for (len = 8; len < 40; len++)
292 if (!test_one_simple(SCLP_READ_CPU_INFO, pagebuf, len, len, PGM_NONE, res))
293 break;
294 report(len == 40, "Insufficient SCCB length (Read CPU info)");
295 }
296
297 /*
298 * Test SCCB page boundary violations.
299 */
test_boundary(void)300 static void test_boundary(void)
301 {
302 const uint32_t cmd = SCLP_CMD_WRITE_EVENT_DATA;
303 const uint16_t res = SCLP_RC_SCCB_BOUNDARY_VIOLATION;
304 WriteEventData *sccb = &sccb_template.data;
305 int len, offset;
306
307 memset(sccb_template.raw, 0, sizeof(sccb_template.raw));
308 sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
309 for (len = 32; len <= 4096; len++) {
310 offset = len & 7 ? len & ~7 : len - 8;
311 for (offset = 4096 - offset; offset < 4096; offset += 8) {
312 sccb->h.length = len;
313 if (!test_one_sccb(cmd, offset + pagebuf, len, PGM_NONE, res))
314 goto out;
315 }
316 }
317 out:
318 report(len > 4096 && offset == 4096, "SCCB page boundary violation");
319 }
320
321 /*
322 * Test excessively long SCCBs.
323 */
test_toolong(void)324 static void test_toolong(void)
325 {
326 const uint32_t cmd = SCLP_CMD_WRITE_EVENT_DATA;
327 const uint16_t res = SCLP_RC_SCCB_BOUNDARY_VIOLATION;
328 WriteEventData *sccb = &sccb_template.data;
329 int len;
330
331 memset(sccb_template.raw, 0, sizeof(sccb_template.raw));
332 sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
333 for (len = 4097; len < 8192; len++) {
334 sccb->h.length = len;
335 if (!test_one_sccb(cmd, pagebuf, PAGE_SIZE, PGM_NONE, res))
336 break;
337 }
338 report(len == 8192, "SCCB bigger than 4k");
339 }
340
341 /*
342 * Test privileged operation.
343 */
test_priv(void)344 static void test_priv(void)
345 {
346 SCCBHeader *h = (SCCBHeader *)pagebuf;
347
348 report_prefix_push("Privileged operation");
349 h->length = 8;
350 expect_pgm_int();
351 enter_pstate();
352 servc(valid_code, __pa(h));
353 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
354 report_prefix_pop();
355 }
356
357 /*
358 * Test addressing exceptions. We need to test SCCB addresses between the
359 * end of available memory and 2GB, because after 2GB a specification
360 * exception is also allowed.
361 * Only applicable if the VM has less than 2GB of memory
362 */
test_addressing(void)363 static void test_addressing(void)
364 {
365 unsigned long i, maxram = get_ram_size();
366
367 /* the VM has more than 2GB of memory */
368 if (maxram >= 0x80000000) {
369 report_skip("Invalid SCCB address");
370 return;
371 }
372 /* test all possible valid addresses immediately after the end of memory
373 * up to 64KB after the end of memory
374 */
375 for (i = 0; i < 0x10000 && i + maxram < 0x80000000; i += 8)
376 if (!test_one_ro(valid_code, MKPTR(i + maxram), PGM_BIT_ADDR, 0))
377 goto out;
378 /* test more addresses until we reach 1MB after end of memory;
379 * increment by a prime number (times 8) in order to test all
380 * possible valid offsets inside pages
381 */
382 for (; i < 0x100000 && i + maxram < 0x80000000 ; i += 808)
383 if (!test_one_ro(valid_code, MKPTR(i + maxram), PGM_BIT_ADDR, 0))
384 goto out;
385 /* test the remaining addresses until we reach address 2GB;
386 * increment by a prime number (times 8) in order to test all
387 * possible valid offsets inside pages
388 */
389 for (; i + maxram < 0x80000000; i += 800024)
390 if (!test_one_ro(valid_code, MKPTR(i + maxram), PGM_BIT_ADDR, 0))
391 goto out;
392 out:
393 report(i + maxram >= 0x80000000, "Invalid SCCB address");
394 }
395
396 /*
397 * Test some bits in the instruction format that are specified to be ignored.
398 */
test_instbits(void)399 static void test_instbits(void)
400 {
401 SCCBHeader *h = (SCCBHeader *)pagebuf;
402 uint64_t bogus_cc = 1;
403 int cc;
404
405 sclp_mark_busy();
406 h->length = 8;
407 sclp_setup_int();
408
409 asm volatile(
410 " tmll %[bogus_cc],3\n"
411 " .insn rre,0xb2204200,%1,%2\n" /* servc %1,%2 */
412 " ipm %0\n"
413 " srl %0,28"
414 : "=&d" (cc)
415 : "d" (valid_code), "a" (__pa(pagebuf)), [bogus_cc] "d" (bogus_cc)
416 : "cc", "memory");
417 /* No exception, but also no command accepted, so no interrupt is
418 * expected. We need to clear the flag manually otherwise we will
419 * loop forever when we try to report failure.
420 */
421 if (cc)
422 sclp_handle_ext();
423 else
424 sclp_wait_busy();
425 report(cc == 0, "Instruction format ignored bits");
426 }
427
428 /*
429 * Find a valid READ INFO command code; not all codes are always allowed, and
430 * probing should be performed in the right order.
431 */
find_valid_sclp_code(void)432 static void find_valid_sclp_code(void)
433 {
434 const unsigned int commands[] = { SCLP_CMDW_READ_SCP_INFO_FORCED,
435 SCLP_CMDW_READ_SCP_INFO };
436 SCCBHeader *h = (SCCBHeader *)pagebuf;
437 int i, cc;
438
439 for (i = 0; i < ARRAY_SIZE(commands); i++) {
440 sclp_mark_busy();
441 memset(h, 0, sizeof(*h));
442 h->length = 4096;
443
444 valid_code = commands[i];
445 cc = sclp_service_call(commands[i], h);
446 if (cc)
447 break;
448 if (h->response_code == SCLP_RC_NORMAL_READ_COMPLETION)
449 return;
450 if (h->response_code != SCLP_RC_INVALID_SCLP_COMMAND)
451 break;
452 }
453 report_abort("READ_SCP_INFO failed");
454 }
455
main(void)456 int main(void)
457 {
458 report_prefix_push("sclp");
459 find_valid_sclp_code();
460
461 /* Test some basic things */
462 test_instbits();
463 test_priv();
464 test_addressing();
465
466 /* Test the specification exceptions */
467 test_sccb_too_short();
468 test_sccb_unaligned();
469 test_sccb_prefix();
470 test_sccb_high();
471
472 /* Test the expected response codes */
473 test_inval();
474 test_short();
475 test_boundary();
476 test_toolong();
477
478 return report_summary();
479 }
480