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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 399 static void test_instbits(void) 400 { 401 SCCBHeader *h = (SCCBHeader *)pagebuf; 402 int cc; 403 404 sclp_mark_busy(); 405 h->length = 8; 406 sclp_setup_int(); 407 408 asm volatile( 409 " .insn rre,0xb2204200,%1,%2\n" /* servc %1,%2 */ 410 " ipm %0\n" 411 " srl %0,28" 412 : "=&d" (cc) : "d" (valid_code), "a" (__pa(pagebuf)) 413 : "cc", "memory"); 414 /* No exception, but also no command accepted, so no interrupt is 415 * expected. We need to clear the flag manually otherwise we will 416 * loop forever when we try to report failure. 417 */ 418 if (cc) 419 sclp_handle_ext(); 420 else 421 sclp_wait_busy(); 422 report(cc == 0, "Instruction format ignored bits"); 423 } 424 425 /** 426 * Find a valid READ INFO command code; not all codes are always allowed, and 427 * probing should be performed in the right order. 428 */ 429 static void find_valid_sclp_code(void) 430 { 431 const unsigned int commands[] = { SCLP_CMDW_READ_SCP_INFO_FORCED, 432 SCLP_CMDW_READ_SCP_INFO }; 433 SCCBHeader *h = (SCCBHeader *)pagebuf; 434 int i, cc; 435 436 for (i = 0; i < ARRAY_SIZE(commands); i++) { 437 sclp_mark_busy(); 438 memset(h, 0, sizeof(*h)); 439 h->length = 4096; 440 441 valid_code = commands[i]; 442 cc = sclp_service_call(commands[i], h); 443 if (cc) 444 break; 445 if (h->response_code == SCLP_RC_NORMAL_READ_COMPLETION) 446 return; 447 if (h->response_code != SCLP_RC_INVALID_SCLP_COMMAND) 448 break; 449 } 450 report_abort("READ_SCP_INFO failed"); 451 } 452 453 int main(void) 454 { 455 report_prefix_push("sclp"); 456 find_valid_sclp_code(); 457 458 /* Test some basic things */ 459 test_instbits(); 460 test_priv(); 461 test_addressing(); 462 463 /* Test the specification exceptions */ 464 test_sccb_too_short(); 465 test_sccb_unaligned(); 466 test_sccb_prefix(); 467 test_sccb_high(); 468 469 /* Test the expected response codes */ 470 test_inval(); 471 test_short(); 472 test_boundary(); 473 test_toolong(); 474 475 return report_summary(); 476 } 477