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