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