1 /* 2 * Boot order test cases. 3 * 4 * Copyright (c) 2013 Red Hat Inc. 5 * 6 * Authors: 7 * Michael S. Tsirkin <mst@redhat.com>, 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 /* 14 * How to add or update the tests or commit changes that affect ACPI tables: 15 * Contributor: 16 * 1. add empty files for new tables, if any, under tests/data/acpi 17 * 2. list any changed files in tests/qtest/bios-tables-test-allowed-diff.h 18 * 3. commit the above *before* making changes that affect the tables 19 * 20 * Contributor or ACPI Maintainer (steps 4-7 need to be redone to resolve conflicts 21 * in binary commit created in step 6): 22 * 23 * After 1-3 above tests will pass but ignore differences with the expected files. 24 * You will also notice that tests/qtest/bios-tables-test-allowed-diff.h lists 25 * a bunch of files. This is your hint that you need to do the below: 26 * 4. Run 27 * make check V=2 28 * this will produce a bunch of warnings about differences 29 * between actual and expected ACPI tables. If you have IASL installed, 30 * they will also be disassembled so you can look at the disassembled 31 * output. If not - disassemble them yourself in any way you like. 32 * Look at the differences - make sure they make sense and match what the 33 * changes you are merging are supposed to do. 34 * Save the changes, preferably in form of ASL diff for the commit log in 35 * step 6. 36 * 37 * 5. From build directory, run: 38 * $(SRC_PATH)/tests/data/acpi/rebuild-expected-aml.sh 39 * 6. Now commit any changes to the expected binary, include diff from step 4 40 * in commit log. 41 * Expected binary updates needs to be a separate patch from the code that 42 * introduces changes to ACPI tables. It lets the maintainer drop 43 * and regenerate binary updates in case of merge conflicts. Further, a code 44 * change is easily reviewable but a binary blob is not (without doing a 45 * disassembly). 46 * 7. Before sending patches to the list (Contributor) 47 * or before doing a pull request (Maintainer), make sure 48 * tests/qtest/bios-tables-test-allowed-diff.h is empty - this will ensure 49 * following changes to ACPI tables will be noticed. 50 * 51 * The resulting patchset/pull request then looks like this: 52 * - patch 1: list changed files in tests/qtest/bios-tables-test-allowed-diff.h. 53 * - patches 2 - n: real changes, may contain multiple patches. 54 * - patch n + 1: update golden master binaries and empty 55 * tests/qtest/bios-tables-test-allowed-diff.h 56 */ 57 58 #include "qemu/osdep.h" 59 #include <glib/gstdio.h> 60 #include "hw/firmware/smbios.h" 61 #include "qemu/bitmap.h" 62 #include "acpi-utils.h" 63 #include "boot-sector.h" 64 #include "tpm-emu.h" 65 #include "hw/acpi/tpm.h" 66 #include "qemu/cutils.h" 67 68 #define MACHINE_PC "pc" 69 #define MACHINE_Q35 "q35" 70 71 #define ACPI_REBUILD_EXPECTED_AML "TEST_ACPI_REBUILD_AML" 72 73 #define OEM_ID "TEST" 74 #define OEM_TABLE_ID "OEM" 75 #define OEM_TEST_ARGS "-machine x-oem-id=" OEM_ID ",x-oem-table-id=" \ 76 OEM_TABLE_ID 77 78 typedef struct { 79 bool tcg_only; 80 const char *machine; 81 const char *machine_param; 82 const char *variant; 83 const char *uefi_fl1; 84 const char *uefi_fl2; 85 const char *blkdev; 86 const char *cd; 87 const uint64_t ram_start; 88 const uint64_t scan_len; 89 uint64_t rsdp_addr; 90 uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */]; 91 GArray *tables; 92 uint64_t smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE__MAX]; 93 SmbiosEntryPoint smbios_ep_table; 94 uint16_t smbios_cpu_max_speed; 95 uint16_t smbios_cpu_curr_speed; 96 uint8_t smbios_core_count; 97 uint16_t smbios_core_count2; 98 uint8_t smbios_thread_count; 99 uint16_t smbios_thread_count2; 100 uint8_t *required_struct_types; 101 int required_struct_types_len; 102 int type4_count; 103 QTestState *qts; 104 } test_data; 105 106 static char disk[] = "tests/acpi-test-disk-XXXXXX"; 107 static const char *data_dir = "tests/data/acpi"; 108 #ifdef CONFIG_IASL 109 static const char *iasl = CONFIG_IASL; 110 #else 111 static const char *iasl; 112 #endif 113 114 static int verbosity_level; 115 116 static bool compare_signature(const AcpiSdtTable *sdt, const char *signature) 117 { 118 return !memcmp(sdt->aml, signature, 4); 119 } 120 121 static void cleanup_table_descriptor(AcpiSdtTable *table) 122 { 123 g_free(table->aml); 124 if (table->aml_file && 125 !table->tmp_files_retain && 126 g_strstr_len(table->aml_file, -1, "aml-")) { 127 unlink(table->aml_file); 128 } 129 g_free(table->aml_file); 130 g_free(table->asl); 131 if (table->asl_file && 132 !table->tmp_files_retain) { 133 unlink(table->asl_file); 134 } 135 g_free(table->asl_file); 136 } 137 138 static void free_test_data(test_data *data) 139 { 140 int i; 141 142 if (!data->tables) { 143 return; 144 } 145 for (i = 0; i < data->tables->len; ++i) { 146 cleanup_table_descriptor(&g_array_index(data->tables, AcpiSdtTable, i)); 147 } 148 149 g_array_free(data->tables, true); 150 } 151 152 static void test_acpi_rsdp_table(test_data *data) 153 { 154 uint8_t *rsdp_table = data->rsdp_table; 155 156 acpi_fetch_rsdp_table(data->qts, data->rsdp_addr, rsdp_table); 157 158 switch (rsdp_table[15 /* Revision offset */]) { 159 case 0: /* ACPI 1.0 RSDP */ 160 /* With rev 1, checksum is only for the first 20 bytes */ 161 g_assert(!acpi_calc_checksum(rsdp_table, 20)); 162 break; 163 case 2: /* ACPI 2.0+ RSDP */ 164 /* With revision 2, we have 2 checksums */ 165 g_assert(!acpi_calc_checksum(rsdp_table, 20)); 166 g_assert(!acpi_calc_checksum(rsdp_table, 36)); 167 break; 168 default: 169 g_assert_not_reached(); 170 } 171 } 172 173 static void test_acpi_rxsdt_table(test_data *data) 174 { 175 const char *sig = "RSDT"; 176 AcpiSdtTable rsdt = {}; 177 int entry_size = 4; 178 int addr_off = 16 /* RsdtAddress */; 179 uint8_t *ent; 180 181 if (data->rsdp_table[15 /* Revision offset */] != 0) { 182 addr_off = 24 /* XsdtAddress */; 183 entry_size = 8; 184 sig = "XSDT"; 185 } 186 /* read [RX]SDT table */ 187 acpi_fetch_table(data->qts, &rsdt.aml, &rsdt.aml_len, 188 &data->rsdp_table[addr_off], entry_size, sig, true); 189 190 /* Load all tables and add to test list directly RSDT referenced tables */ 191 ACPI_FOREACH_RSDT_ENTRY(rsdt.aml, rsdt.aml_len, ent, entry_size) { 192 AcpiSdtTable ssdt_table = {}; 193 194 acpi_fetch_table(data->qts, &ssdt_table.aml, &ssdt_table.aml_len, ent, 195 entry_size, NULL, true); 196 /* Add table to ASL test tables list */ 197 g_array_append_val(data->tables, ssdt_table); 198 } 199 cleanup_table_descriptor(&rsdt); 200 } 201 202 static void test_acpi_fadt_table(test_data *data) 203 { 204 /* FADT table is 1st */ 205 AcpiSdtTable table = g_array_index(data->tables, typeof(table), 0); 206 uint8_t *fadt_aml = table.aml; 207 uint32_t fadt_len = table.aml_len; 208 uint32_t val; 209 int dsdt_offset = 40 /* DSDT */; 210 int dsdt_entry_size = 4; 211 212 g_assert(compare_signature(&table, "FACP")); 213 214 /* Since DSDT/FACS isn't in RSDT, add them to ASL test list manually */ 215 memcpy(&val, fadt_aml + 112 /* Flags */, 4); 216 val = le32_to_cpu(val); 217 if (!(val & 1UL << 20 /* HW_REDUCED_ACPI */)) { 218 acpi_fetch_table(data->qts, &table.aml, &table.aml_len, 219 fadt_aml + 36 /* FIRMWARE_CTRL */, 4, "FACS", false); 220 g_array_append_val(data->tables, table); 221 } 222 223 memcpy(&val, fadt_aml + dsdt_offset, 4); 224 val = le32_to_cpu(val); 225 if (!val) { 226 dsdt_offset = 140 /* X_DSDT */; 227 dsdt_entry_size = 8; 228 } 229 acpi_fetch_table(data->qts, &table.aml, &table.aml_len, 230 fadt_aml + dsdt_offset, dsdt_entry_size, "DSDT", true); 231 g_array_append_val(data->tables, table); 232 233 memset(fadt_aml + 36, 0, 4); /* sanitize FIRMWARE_CTRL ptr */ 234 memset(fadt_aml + 40, 0, 4); /* sanitize DSDT ptr */ 235 if (fadt_aml[8 /* FADT Major Version */] >= 3) { 236 memset(fadt_aml + 132, 0, 8); /* sanitize X_FIRMWARE_CTRL ptr */ 237 memset(fadt_aml + 140, 0, 8); /* sanitize X_DSDT ptr */ 238 } 239 240 /* update checksum */ 241 fadt_aml[9 /* Checksum */] = 0; 242 fadt_aml[9 /* Checksum */] -= acpi_calc_checksum(fadt_aml, fadt_len); 243 } 244 245 static void dump_aml_files(test_data *data, bool rebuild) 246 { 247 AcpiSdtTable *sdt; 248 GError *error = NULL; 249 gchar *aml_file = NULL; 250 gint fd; 251 ssize_t ret; 252 int i; 253 254 for (i = 0; i < data->tables->len; ++i) { 255 const char *ext = data->variant ? data->variant : ""; 256 sdt = &g_array_index(data->tables, AcpiSdtTable, i); 257 g_assert(sdt->aml); 258 259 if (rebuild) { 260 aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, 261 sdt->aml, ext); 262 fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT, 263 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); 264 if (fd < 0) { 265 perror(aml_file); 266 } 267 g_assert(fd >= 0); 268 } else { 269 fd = g_file_open_tmp("aml-XXXXXX", &sdt->aml_file, &error); 270 g_assert_no_error(error); 271 } 272 273 ret = qemu_write_full(fd, sdt->aml, sdt->aml_len); 274 g_assert(ret == sdt->aml_len); 275 276 close(fd); 277 278 g_free(aml_file); 279 } 280 } 281 282 static bool create_tmp_asl(AcpiSdtTable *sdt) 283 { 284 GError *error = NULL; 285 gint fd; 286 287 fd = g_file_open_tmp("asl-XXXXXX.dsl", &sdt->asl_file, &error); 288 g_assert_no_error(error); 289 close(fd); 290 291 return false; 292 } 293 294 static bool load_asl(GArray *sdts, AcpiSdtTable *sdt) 295 { 296 AcpiSdtTable *temp; 297 GError *error = NULL; 298 GString *command_line = g_string_new(iasl); 299 gchar *out, *out_err; 300 gboolean ret; 301 int i; 302 303 create_tmp_asl(sdt); 304 305 /* build command line */ 306 g_string_append_printf(command_line, " -p %s ", sdt->asl_file); 307 if (compare_signature(sdt, "DSDT") || 308 compare_signature(sdt, "SSDT")) { 309 for (i = 0; i < sdts->len; ++i) { 310 temp = &g_array_index(sdts, AcpiSdtTable, i); 311 if (compare_signature(temp, "DSDT") || 312 compare_signature(temp, "SSDT")) { 313 g_string_append_printf(command_line, "-e %s ", temp->aml_file); 314 } 315 } 316 } 317 g_string_append_printf(command_line, "-d %s", sdt->aml_file); 318 319 /* pass 'out' and 'out_err' in order to be redirected */ 320 ret = g_spawn_command_line_sync(command_line->str, &out, &out_err, NULL, &error); 321 g_assert_no_error(error); 322 if (ret) { 323 ret = g_file_get_contents(sdt->asl_file, &sdt->asl, 324 &sdt->asl_len, &error); 325 g_assert(ret); 326 g_assert_no_error(error); 327 ret = (sdt->asl_len > 0); 328 } 329 330 g_free(out); 331 g_free(out_err); 332 g_string_free(command_line, true); 333 334 return !ret; 335 } 336 337 #define COMMENT_END "*/" 338 #define DEF_BLOCK "DefinitionBlock (" 339 #define BLOCK_NAME_END "," 340 341 static GString *normalize_asl(gchar *asl_code) 342 { 343 GString *asl = g_string_new(asl_code); 344 gchar *comment, *block_name; 345 346 /* strip comments (different generation days) */ 347 comment = g_strstr_len(asl->str, asl->len, COMMENT_END); 348 if (comment) { 349 comment += strlen(COMMENT_END); 350 while (*comment == '\n') { 351 comment++; 352 } 353 asl = g_string_erase(asl, 0, comment - asl->str); 354 } 355 356 /* strip def block name (it has file path in it) */ 357 if (g_str_has_prefix(asl->str, DEF_BLOCK)) { 358 block_name = g_strstr_len(asl->str, asl->len, BLOCK_NAME_END); 359 g_assert(block_name); 360 asl = g_string_erase(asl, 0, 361 block_name + sizeof(BLOCK_NAME_END) - asl->str); 362 } 363 364 return asl; 365 } 366 367 static GArray *load_expected_aml(test_data *data) 368 { 369 int i; 370 AcpiSdtTable *sdt; 371 GError *error = NULL; 372 gboolean ret; 373 gsize aml_len; 374 375 GArray *exp_tables = g_array_new(false, true, sizeof(AcpiSdtTable)); 376 if (verbosity_level >= 2) { 377 fputc('\n', stderr); 378 } 379 for (i = 0; i < data->tables->len; ++i) { 380 AcpiSdtTable exp_sdt; 381 gchar *aml_file = NULL; 382 const char *ext = data->variant ? data->variant : ""; 383 384 sdt = &g_array_index(data->tables, AcpiSdtTable, i); 385 386 memset(&exp_sdt, 0, sizeof(exp_sdt)); 387 388 try_again: 389 aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, 390 sdt->aml, ext); 391 if (verbosity_level >= 2) { 392 fprintf(stderr, "Looking for expected file '%s'\n", aml_file); 393 } 394 if (g_file_test(aml_file, G_FILE_TEST_EXISTS)) { 395 exp_sdt.aml_file = aml_file; 396 } else if (*ext != '\0') { 397 /* try fallback to generic (extension less) expected file */ 398 ext = ""; 399 g_free(aml_file); 400 goto try_again; 401 } 402 g_assert(exp_sdt.aml_file); 403 if (verbosity_level >= 2) { 404 fprintf(stderr, "Using expected file '%s'\n", aml_file); 405 } 406 ret = g_file_get_contents(aml_file, (gchar **)&exp_sdt.aml, 407 &aml_len, &error); 408 exp_sdt.aml_len = aml_len; 409 g_assert(ret); 410 g_assert_no_error(error); 411 g_assert(exp_sdt.aml); 412 if (!exp_sdt.aml_len) { 413 fprintf(stderr, "Warning! zero length expected file '%s'\n", 414 aml_file); 415 } 416 417 g_array_append_val(exp_tables, exp_sdt); 418 } 419 420 return exp_tables; 421 } 422 423 static bool test_acpi_find_diff_allowed(AcpiSdtTable *sdt) 424 { 425 const gchar *allowed_diff_file[] = { 426 #include "bios-tables-test-allowed-diff.h" 427 NULL 428 }; 429 const gchar **f; 430 431 for (f = allowed_diff_file; *f; ++f) { 432 if (!g_strcmp0(sdt->aml_file, *f)) { 433 return true; 434 } 435 } 436 return false; 437 } 438 439 /* test the list of tables in @data->tables against reference tables */ 440 static void test_acpi_asl(test_data *data) 441 { 442 int i; 443 AcpiSdtTable *sdt, *exp_sdt; 444 test_data exp_data = {}; 445 gboolean exp_err, err, all_tables_match = true; 446 447 exp_data.tables = load_expected_aml(data); 448 dump_aml_files(data, false); 449 for (i = 0; i < data->tables->len; ++i) { 450 GString *asl, *exp_asl; 451 452 sdt = &g_array_index(data->tables, AcpiSdtTable, i); 453 exp_sdt = &g_array_index(exp_data.tables, AcpiSdtTable, i); 454 455 if (sdt->aml_len == exp_sdt->aml_len && 456 !memcmp(sdt->aml, exp_sdt->aml, sdt->aml_len)) { 457 /* Identical table binaries: no need to disassemble. */ 458 continue; 459 } 460 461 fprintf(stderr, 462 "acpi-test: Warning! %.4s binary file mismatch. " 463 "Actual [aml:%s], Expected [aml:%s].\n" 464 "See source file tests/qtest/bios-tables-test.c " 465 "for instructions on how to update expected files.\n", 466 exp_sdt->aml, sdt->aml_file, exp_sdt->aml_file); 467 468 all_tables_match = all_tables_match && 469 test_acpi_find_diff_allowed(exp_sdt); 470 471 /* 472 * don't try to decompile if IASL isn't present, in this case user 473 * will just 'get binary file mismatch' warnings and test failure 474 */ 475 if (!iasl) { 476 continue; 477 } 478 479 err = load_asl(data->tables, sdt); 480 asl = normalize_asl(sdt->asl); 481 482 /* 483 * If expected file is empty - it's likely that it was a stub just 484 * created for step 1 above: we do want to decompile the actual one. 485 */ 486 if (exp_sdt->aml_len) { 487 exp_err = load_asl(exp_data.tables, exp_sdt); 488 exp_asl = normalize_asl(exp_sdt->asl); 489 } else { 490 exp_err = create_tmp_asl(exp_sdt); 491 exp_asl = g_string_new(""); 492 } 493 494 /* TODO: check for warnings */ 495 g_assert(!err || exp_err || !exp_sdt->aml_len); 496 497 if (g_strcmp0(asl->str, exp_asl->str)) { 498 sdt->tmp_files_retain = true; 499 if (exp_err) { 500 fprintf(stderr, 501 "Warning! iasl couldn't parse the expected aml\n"); 502 } else { 503 exp_sdt->tmp_files_retain = true; 504 fprintf(stderr, 505 "acpi-test: Warning! %.4s mismatch. " 506 "Actual [asl:%s, aml:%s], Expected [asl:%s, aml:%s].\n", 507 exp_sdt->aml, sdt->asl_file, sdt->aml_file, 508 exp_sdt->asl_file, exp_sdt->aml_file); 509 fflush(stderr); 510 if (verbosity_level >= 1) { 511 const char *diff_env = getenv("DIFF"); 512 const char *diff_cmd = diff_env ? diff_env : "diff -U 16"; 513 char *diff = g_strdup_printf("%s %s %s", diff_cmd, 514 exp_sdt->asl_file, sdt->asl_file); 515 int out = dup(STDOUT_FILENO); 516 int ret G_GNUC_UNUSED; 517 int dupret; 518 519 g_assert(out >= 0); 520 dupret = dup2(STDERR_FILENO, STDOUT_FILENO); 521 g_assert(dupret >= 0); 522 ret = system(diff) ; 523 dupret = dup2(out, STDOUT_FILENO); 524 g_assert(dupret >= 0); 525 close(out); 526 g_free(diff); 527 } 528 } 529 } 530 g_string_free(asl, true); 531 g_string_free(exp_asl, true); 532 } 533 if (!iasl && !all_tables_match) { 534 fprintf(stderr, "to see ASL diff between mismatched files install IASL," 535 " rebuild QEMU from scratch and re-run tests with V=1" 536 " environment variable set"); 537 } 538 g_assert(all_tables_match); 539 540 free_test_data(&exp_data); 541 } 542 543 static bool smbios_ep2_table_ok(test_data *data, uint32_t addr) 544 { 545 struct smbios_21_entry_point *ep_table = &data->smbios_ep_table.ep21; 546 547 qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table)); 548 if (memcmp(ep_table->anchor_string, "_SM_", 4)) { 549 return false; 550 } 551 if (memcmp(ep_table->intermediate_anchor_string, "_DMI_", 5)) { 552 return false; 553 } 554 if (ep_table->structure_table_length == 0) { 555 return false; 556 } 557 if (ep_table->number_of_structures == 0) { 558 return false; 559 } 560 if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table) || 561 acpi_calc_checksum((uint8_t *)ep_table + 0x10, 562 sizeof *ep_table - 0x10)) { 563 return false; 564 } 565 return true; 566 } 567 568 static bool smbios_ep3_table_ok(test_data *data, uint64_t addr) 569 { 570 struct smbios_30_entry_point *ep_table = &data->smbios_ep_table.ep30; 571 572 qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table)); 573 if (memcmp(ep_table->anchor_string, "_SM3_", 5)) { 574 return false; 575 } 576 577 if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) { 578 return false; 579 } 580 581 return true; 582 } 583 584 static SmbiosEntryPointType test_smbios_entry_point(test_data *data) 585 { 586 uint32_t off; 587 588 /* find smbios entry point structure */ 589 for (off = 0xf0000; off < 0x100000; off += 0x10) { 590 uint8_t sig[] = "_SM_", sig3[] = "_SM3_"; 591 int i; 592 593 for (i = 0; i < sizeof sig - 1; ++i) { 594 sig[i] = qtest_readb(data->qts, off + i); 595 } 596 597 if (!memcmp(sig, "_SM_", sizeof sig)) { 598 /* signature match, but is this a valid entry point? */ 599 if (smbios_ep2_table_ok(data, off)) { 600 data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] = off; 601 } 602 } 603 604 for (i = 0; i < sizeof sig3 - 1; ++i) { 605 sig3[i] = qtest_readb(data->qts, off + i); 606 } 607 608 if (!memcmp(sig3, "_SM3_", sizeof sig3)) { 609 if (smbios_ep3_table_ok(data, off)) { 610 data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] = off; 611 /* found 64-bit entry point, no need to look for 32-bit one */ 612 break; 613 } 614 } 615 } 616 617 /* found at least one entry point */ 618 g_assert_true(data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] || 619 data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64]); 620 621 return data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] ? 622 SMBIOS_ENTRY_POINT_TYPE_64 : SMBIOS_ENTRY_POINT_TYPE_32; 623 } 624 625 static inline bool smbios_single_instance(uint8_t type) 626 { 627 switch (type) { 628 case 0: 629 case 1: 630 case 2: 631 case 3: 632 case 16: 633 case 32: 634 case 127: 635 return true; 636 default: 637 return false; 638 } 639 } 640 641 static void smbios_cpu_test(test_data *data, uint32_t addr, 642 SmbiosEntryPointType ep_type) 643 { 644 uint8_t core_count, expected_core_count = data->smbios_core_count; 645 uint8_t thread_count, expected_thread_count = data->smbios_thread_count; 646 uint16_t speed, expected_speed[2]; 647 uint16_t core_count2, expected_core_count2 = data->smbios_core_count2; 648 uint16_t thread_count2, expected_thread_count2 = data->smbios_thread_count2; 649 int offset[2]; 650 int i; 651 652 /* Check CPU speed for backward compatibility */ 653 offset[0] = offsetof(struct smbios_type_4, max_speed); 654 offset[1] = offsetof(struct smbios_type_4, current_speed); 655 expected_speed[0] = data->smbios_cpu_max_speed ? : 2000; 656 expected_speed[1] = data->smbios_cpu_curr_speed ? : 2000; 657 658 for (i = 0; i < 2; i++) { 659 speed = qtest_readw(data->qts, addr + offset[i]); 660 g_assert_cmpuint(speed, ==, expected_speed[i]); 661 } 662 663 core_count = qtest_readb(data->qts, 664 addr + offsetof(struct smbios_type_4, core_count)); 665 666 if (expected_core_count) { 667 g_assert_cmpuint(core_count, ==, expected_core_count); 668 } 669 670 thread_count = qtest_readb(data->qts, 671 addr + offsetof(struct smbios_type_4, thread_count)); 672 673 if (expected_thread_count) { 674 g_assert_cmpuint(thread_count, ==, expected_thread_count); 675 } 676 677 if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) { 678 core_count2 = qtest_readw(data->qts, 679 addr + offsetof(struct smbios_type_4, core_count2)); 680 681 /* Core Count has reached its limit, checking Core Count 2 */ 682 if (expected_core_count == 0xFF && expected_core_count2) { 683 g_assert_cmpuint(core_count2, ==, expected_core_count2); 684 } 685 686 thread_count2 = qtest_readw(data->qts, 687 addr + offsetof(struct smbios_type_4, 688 thread_count2)); 689 690 /* Thread Count has reached its limit, checking Thread Count 2 */ 691 if (expected_thread_count == 0xFF && expected_thread_count2) { 692 g_assert_cmpuint(thread_count2, ==, expected_thread_count2); 693 } 694 } 695 } 696 697 static void smbios_type4_count_test(test_data *data, int type4_count) 698 { 699 int expected_type4_count = data->type4_count; 700 701 if (expected_type4_count) { 702 g_assert_cmpuint(type4_count, ==, expected_type4_count); 703 } 704 } 705 706 static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type) 707 { 708 DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 }; 709 710 SmbiosEntryPoint *ep_table = &data->smbios_ep_table; 711 int i = 0, len, max_len = 0, type4_count = 0; 712 uint8_t type, prv, crt; 713 uint64_t addr; 714 715 if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) { 716 addr = le32_to_cpu(ep_table->ep21.structure_table_address); 717 } else { 718 addr = le64_to_cpu(ep_table->ep30.structure_table_address); 719 } 720 721 /* walk the smbios tables */ 722 do { 723 724 /* grab type and formatted area length from struct header */ 725 type = qtest_readb(data->qts, addr); 726 g_assert_cmpuint(type, <=, SMBIOS_MAX_TYPE); 727 len = qtest_readb(data->qts, addr + 1); 728 729 /* single-instance structs must not have been encountered before */ 730 if (smbios_single_instance(type)) { 731 g_assert(!test_bit(type, struct_bitmap)); 732 } 733 set_bit(type, struct_bitmap); 734 735 if (type == 4) { 736 smbios_cpu_test(data, addr, ep_type); 737 type4_count++; 738 } 739 740 /* seek to end of unformatted string area of this struct ("\0\0") */ 741 prv = crt = 1; 742 while (prv || crt) { 743 prv = crt; 744 crt = qtest_readb(data->qts, addr + len); 745 len++; 746 } 747 748 /* keep track of max. struct size */ 749 if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && max_len < len) { 750 max_len = len; 751 g_assert_cmpuint(max_len, <=, ep_table->ep21.max_structure_size); 752 } 753 754 /* start of next structure */ 755 addr += len; 756 757 /* 758 * Until all structures have been scanned (ep21) 759 * or an EOF structure is found (ep30) 760 */ 761 } while (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ? 762 ++i < le16_to_cpu(ep_table->ep21.number_of_structures) : 763 type != 127); 764 765 if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) { 766 /* 767 * Total table length and max struct size 768 * must match entry point values 769 */ 770 g_assert_cmpuint(le16_to_cpu(ep_table->ep21.structure_table_length), ==, 771 addr - le32_to_cpu(ep_table->ep21.structure_table_address)); 772 773 g_assert_cmpuint(le16_to_cpu(ep_table->ep21.max_structure_size), ==, 774 max_len); 775 } 776 777 /* required struct types must all be present */ 778 for (i = 0; i < data->required_struct_types_len; i++) { 779 g_assert(test_bit(data->required_struct_types[i], struct_bitmap)); 780 } 781 782 smbios_type4_count_test(data, type4_count); 783 } 784 785 static void test_acpi_load_tables(test_data *data) 786 { 787 if (data->uefi_fl1 && data->uefi_fl2) { /* use UEFI */ 788 g_assert(data->scan_len); 789 data->rsdp_addr = acpi_find_rsdp_address_uefi(data->qts, 790 data->ram_start, data->scan_len); 791 } else { 792 boot_sector_test(data->qts); 793 data->rsdp_addr = acpi_find_rsdp_address(data->qts); 794 g_assert_cmphex(data->rsdp_addr, <, 0x100000); 795 } 796 797 data->tables = g_array_new(false, true, sizeof(AcpiSdtTable)); 798 test_acpi_rsdp_table(data); 799 test_acpi_rxsdt_table(data); 800 test_acpi_fadt_table(data); 801 } 802 803 static char *test_acpi_create_args(test_data *data, const char *params) 804 { 805 char *args; 806 807 if (data->uefi_fl1 && data->uefi_fl2) { /* use UEFI */ 808 /* 809 * TODO: convert '-drive if=pflash' to new syntax (see e33763be7cd3) 810 * when arm/virt boad starts to support it. 811 */ 812 if (data->cd) { 813 args = g_strdup_printf("-machine %s%s %s -accel tcg " 814 "-nodefaults -nographic " 815 "-drive if=pflash,format=raw,file=%s,readonly=on " 816 "-drive if=pflash,format=raw,file=%s,snapshot=on -cdrom %s %s", 817 data->machine, data->machine_param ?: "", 818 data->tcg_only ? "" : "-accel kvm", 819 data->uefi_fl1, data->uefi_fl2, data->cd, params ? params : ""); 820 } else { 821 args = g_strdup_printf("-machine %s%s %s -accel tcg " 822 "-nodefaults -nographic " 823 "-drive if=pflash,format=raw,file=%s,readonly=on " 824 "-drive if=pflash,format=raw,file=%s,snapshot=on %s", 825 data->machine, data->machine_param ?: "", 826 data->tcg_only ? "" : "-accel kvm", 827 data->uefi_fl1, data->uefi_fl2, params ? params : ""); 828 } 829 } else { 830 args = g_strdup_printf("-machine %s%s %s -accel tcg " 831 "-net none %s " 832 "-drive id=hd0,if=none,file=%s,format=raw " 833 "-device %s,drive=hd0 ", 834 data->machine, data->machine_param ?: "", 835 data->tcg_only ? "" : "-accel kvm", 836 params ? params : "", disk, 837 data->blkdev ?: "ide-hd"); 838 } 839 return args; 840 } 841 842 static void test_vm_prepare(const char *params, test_data *data) 843 { 844 char *args = test_acpi_create_args(data, params); 845 data->qts = qtest_init(args); 846 g_free(args); 847 } 848 849 static void process_acpi_tables_noexit(test_data *data) 850 { 851 test_acpi_load_tables(data); 852 853 if (getenv(ACPI_REBUILD_EXPECTED_AML)) { 854 dump_aml_files(data, true); 855 } else { 856 test_acpi_asl(data); 857 } 858 859 /* 860 * TODO: make SMBIOS tests work with UEFI firmware, 861 * Bug on uefi-test-tools to provide entry point: 862 * https://bugs.launchpad.net/qemu/+bug/1821884 863 */ 864 if (!(data->uefi_fl1 && data->uefi_fl2)) { 865 SmbiosEntryPointType ep_type = test_smbios_entry_point(data); 866 test_smbios_structs(data, ep_type); 867 } 868 } 869 870 static void process_acpi_tables(test_data *data) 871 { 872 process_acpi_tables_noexit(data); 873 qtest_quit(data->qts); 874 } 875 876 static void test_acpi_one(const char *params, test_data *data) 877 { 878 test_vm_prepare(params, data); 879 process_acpi_tables(data); 880 } 881 882 static uint8_t base_required_struct_types[] = { 883 0, 1, 3, 4, 16, 17, 19, 32, 127 884 }; 885 886 static void test_acpi_piix4_tcg(void) 887 { 888 test_data data = {}; 889 890 /* Supplying -machine accel argument overrides the default (qtest). 891 * This is to make guest actually run. 892 */ 893 data.machine = MACHINE_PC; 894 data.required_struct_types = base_required_struct_types; 895 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 896 test_acpi_one(NULL, &data); 897 free_test_data(&data); 898 } 899 900 static void test_acpi_piix4_tcg_bridge(void) 901 { 902 test_data data = {}; 903 904 data.machine = MACHINE_PC; 905 data.variant = ".bridge"; 906 data.required_struct_types = base_required_struct_types; 907 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 908 test_vm_prepare("-S" 909 " -device pci-bridge,chassis_nr=1" 910 " -device pci-bridge,bus=pci.1,addr=1.0,chassis_nr=2" 911 " -device pci-testdev,bus=pci.0,addr=5.0" 912 " -device pci-testdev,bus=pci.1", &data); 913 914 /* hotplugged bridges section */ 915 qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr", 916 "{'bus': 'pci.1', 'addr': '2.0', 'chassis_nr': 3 }"); 917 qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr_multifunc", 918 "{'bus': 'pci.1', 'addr': '0xf.1', 'chassis_nr': 4 }"); 919 qtest_qmp_device_add(data.qts, "pci-bridge", "hpbrhost", 920 "{'bus': 'pci.0', 'addr': '4.0', 'chassis_nr': 5 }"); 921 qtest_qmp_device_add(data.qts, "pci-testdev", "d1", "{'bus': 'pci.0' }"); 922 qtest_qmp_device_add(data.qts, "pci-testdev", "d2", "{'bus': 'pci.1' }"); 923 qtest_qmp_device_add(data.qts, "pci-testdev", "d3", "{'bus': 'hpbr', " 924 "'addr': '1.0' }"); 925 qtest_qmp_send(data.qts, "{'execute':'cont' }"); 926 qtest_qmp_eventwait(data.qts, "RESUME"); 927 928 process_acpi_tables_noexit(&data); 929 free_test_data(&data); 930 931 /* check that reboot/reset doesn't change any ACPI tables */ 932 qtest_qmp_send(data.qts, "{'execute':'system_reset' }"); 933 process_acpi_tables(&data); 934 free_test_data(&data); 935 } 936 937 static void test_acpi_piix4_no_root_hotplug(void) 938 { 939 test_data data = {}; 940 941 data.machine = MACHINE_PC; 942 data.variant = ".roothp"; 943 data.required_struct_types = base_required_struct_types; 944 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 945 test_acpi_one("-global PIIX4_PM.acpi-root-pci-hotplug=off " 946 "-device pci-bridge,chassis_nr=1 " 947 "-device pci-bridge,bus=pci.1,addr=1.0,chassis_nr=2 " 948 "-device pci-testdev,bus=pci.0 " 949 "-device pci-testdev,bus=pci.1", &data); 950 free_test_data(&data); 951 } 952 953 static void test_acpi_piix4_no_bridge_hotplug(void) 954 { 955 test_data data = {}; 956 957 data.machine = MACHINE_PC; 958 data.variant = ".hpbridge"; 959 data.required_struct_types = base_required_struct_types; 960 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 961 test_acpi_one("-global PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off " 962 "-device pci-bridge,chassis_nr=1 " 963 "-device pci-bridge,bus=pci.1,addr=1.0,chassis_nr=2 " 964 "-device pci-testdev,bus=pci.0 " 965 "-device pci-testdev,bus=pci.1,addr=2.0", &data); 966 free_test_data(&data); 967 } 968 969 static void test_acpi_piix4_no_acpi_pci_hotplug(void) 970 { 971 test_data data = {}; 972 973 data.machine = MACHINE_PC; 974 data.variant = ".hpbrroot"; 975 data.required_struct_types = base_required_struct_types; 976 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 977 test_acpi_one("-global PIIX4_PM.acpi-root-pci-hotplug=off " 978 "-global PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off " 979 "-device pci-bridge,chassis_nr=1,addr=4.0 " 980 "-device pci-testdev,bus=pci.0,addr=5.0 " 981 "-device pci-testdev,bus=pci.0,addr=6.0,acpi-index=101 " 982 "-device pci-testdev,bus=pci.1,addr=1.0 " 983 "-device pci-testdev,bus=pci.1,addr=2.0,acpi-index=201 " 984 "-device pci-bridge,id=nhpbr,chassis_nr=2,shpc=off,addr=7.0 " 985 "-device pci-testdev,bus=nhpbr,addr=1.0,acpi-index=301 " 986 , &data); 987 free_test_data(&data); 988 } 989 990 static void test_acpi_q35_tcg(void) 991 { 992 test_data data = {}; 993 994 data.machine = MACHINE_Q35; 995 data.required_struct_types = base_required_struct_types; 996 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 997 test_acpi_one(NULL, &data); 998 free_test_data(&data); 999 1000 data.smbios_cpu_max_speed = 3000; 1001 data.smbios_cpu_curr_speed = 2600; 1002 test_acpi_one("-smbios type=4,max-speed=3000,current-speed=2600", &data); 1003 free_test_data(&data); 1004 } 1005 1006 static void test_acpi_q35_tcg_type4_count(void) 1007 { 1008 test_data data = { 1009 .machine = MACHINE_Q35, 1010 .variant = ".type4-count", 1011 .required_struct_types = base_required_struct_types, 1012 .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), 1013 .type4_count = 5, 1014 }; 1015 1016 test_acpi_one("-machine smbios-entry-point-type=64 " 1017 "-smp cpus=100,maxcpus=120,sockets=5," 1018 "dies=2,cores=4,threads=3", &data); 1019 free_test_data(&data); 1020 } 1021 1022 static void test_acpi_q35_tcg_core_count(void) 1023 { 1024 test_data data = { 1025 .machine = MACHINE_Q35, 1026 .variant = ".core-count", 1027 .required_struct_types = base_required_struct_types, 1028 .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), 1029 .smbios_core_count = 9, 1030 .smbios_core_count2 = 9, 1031 }; 1032 1033 test_acpi_one("-machine smbios-entry-point-type=64 " 1034 "-smp 54,sockets=2,dies=3,cores=3,threads=3", 1035 &data); 1036 free_test_data(&data); 1037 } 1038 1039 static void test_acpi_q35_tcg_core_count2(void) 1040 { 1041 test_data data = { 1042 .machine = MACHINE_Q35, 1043 .variant = ".core-count2", 1044 .required_struct_types = base_required_struct_types, 1045 .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), 1046 .smbios_core_count = 0xFF, 1047 .smbios_core_count2 = 260, 1048 }; 1049 1050 test_acpi_one("-machine smbios-entry-point-type=64 " 1051 "-smp 260,dies=2,cores=130,threads=1", 1052 &data); 1053 free_test_data(&data); 1054 } 1055 1056 static void test_acpi_q35_tcg_thread_count(void) 1057 { 1058 test_data data = { 1059 .machine = MACHINE_Q35, 1060 .variant = ".thread-count", 1061 .required_struct_types = base_required_struct_types, 1062 .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), 1063 .smbios_thread_count = 27, 1064 .smbios_thread_count2 = 27, 1065 }; 1066 1067 test_acpi_one("-machine smbios-entry-point-type=64 " 1068 "-smp cpus=15,maxcpus=54,sockets=2,dies=3,cores=3,threads=3", 1069 &data); 1070 free_test_data(&data); 1071 } 1072 1073 static void test_acpi_q35_tcg_thread_count2(void) 1074 { 1075 test_data data = { 1076 .machine = MACHINE_Q35, 1077 .variant = ".thread-count2", 1078 .required_struct_types = base_required_struct_types, 1079 .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), 1080 .smbios_thread_count = 0xFF, 1081 .smbios_thread_count2 = 260, 1082 }; 1083 1084 test_acpi_one("-machine smbios-entry-point-type=64 " 1085 "-smp cpus=210,maxcpus=260,dies=2,cores=65,threads=2", 1086 &data); 1087 free_test_data(&data); 1088 } 1089 1090 static void test_acpi_q35_tcg_bridge(void) 1091 { 1092 test_data data = {}; 1093 1094 data.machine = MACHINE_Q35; 1095 data.variant = ".bridge"; 1096 data.required_struct_types = base_required_struct_types; 1097 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 1098 test_acpi_one("-device pci-bridge,chassis_nr=1,id=br1" 1099 " -device pci-testdev,bus=pcie.0" 1100 " -device pci-testdev,bus=br1", &data); 1101 free_test_data(&data); 1102 } 1103 1104 static void test_acpi_q35_tcg_no_acpi_hotplug(void) 1105 { 1106 test_data data = {}; 1107 1108 data.machine = MACHINE_Q35; 1109 data.variant = ".noacpihp"; 1110 data.required_struct_types = base_required_struct_types; 1111 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 1112 test_acpi_one("-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off" 1113 " -device pci-testdev,bus=pcie.0,acpi-index=101,addr=3.0" 1114 " -device pci-bridge,chassis_nr=1,id=shpcbr,addr=4.0" 1115 " -device pci-testdev,bus=shpcbr,addr=1.0,acpi-index=201" 1116 " -device pci-bridge,chassis_nr=2,shpc=off,id=noshpcbr,addr=5.0" 1117 " -device pci-testdev,bus=noshpcbr,addr=1.0,acpi-index=301" 1118 " -device pcie-root-port,id=hprp,port=0x0,chassis=1,addr=6.0" 1119 " -device pci-testdev,bus=hprp,acpi-index=401" 1120 " -device pcie-root-port,id=nohprp,port=0x0,chassis=2,hotplug=off," 1121 "addr=7.0" 1122 " -device pci-testdev,bus=nohprp,acpi-index=501" 1123 " -device pcie-root-port,id=nohprpint,port=0x0,chassis=3,hotplug=off," 1124 "multifunction=on,addr=8.0" 1125 " -device pci-testdev,bus=nohprpint,acpi-index=601,addr=0.1" 1126 " -device pcie-root-port,id=hprp2,port=0x0,chassis=4,bus=nohprpint," 1127 "addr=0.2" 1128 " -device pci-testdev,bus=hprp2,acpi-index=602" 1129 , &data); 1130 free_test_data(&data); 1131 } 1132 1133 static void test_acpi_q35_multif_bridge(void) 1134 { 1135 test_data data = { 1136 .machine = MACHINE_Q35, 1137 .variant = ".multi-bridge", 1138 }; 1139 test_vm_prepare("-S" 1140 " -device virtio-balloon,id=balloon0,addr=0x4.0x2" 1141 " -device pcie-root-port,id=rp0,multifunction=on," 1142 "port=0x0,chassis=1,addr=0x2" 1143 " -device pcie-root-port,id=rp1,port=0x1,chassis=2,addr=0x3.0x1" 1144 " -device pcie-root-port,id=rp2,port=0x0,chassis=3,bus=rp1,addr=0.0" 1145 " -device pci-bridge,bus=rp2,chassis_nr=4,id=br1" 1146 " -device pcie-root-port,id=rphptgt1,port=0x0,chassis=5,addr=2.1" 1147 " -device pcie-root-port,id=rphptgt2,port=0x0,chassis=6,addr=2.2" 1148 " -device pcie-root-port,id=rphptgt3,port=0x0,chassis=7,addr=2.3" 1149 " -device pci-testdev,bus=pcie.0,addr=2.4" 1150 " -device pci-testdev,bus=pcie.0,addr=2.5,acpi-index=102" 1151 " -device pci-testdev,bus=pcie.0,addr=5.0" 1152 " -device pci-testdev,bus=pcie.0,addr=0xf.0,acpi-index=101" 1153 " -device pci-testdev,bus=rp0,addr=0.0" 1154 " -device pci-testdev,bus=br1" 1155 " -device pcie-root-port,id=rpnohp,chassis=8,addr=0xA.0,hotplug=off" 1156 " -device pcie-root-port,id=rp3,chassis=9,bus=rpnohp" 1157 , &data); 1158 1159 /* hotplugged bridges section */ 1160 qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr1", 1161 "{'bus': 'br1', 'addr': '6.0', 'chassis_nr': 128 }"); 1162 qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr2-multiif", 1163 "{ 'bus': 'br1', 'addr': '2.2', 'chassis_nr': 129 }"); 1164 qtest_qmp_device_add(data.qts, "pcie-pci-bridge", "hpbr3", 1165 "{'bus': 'rphptgt1', 'addr': '0.0' }"); 1166 qtest_qmp_device_add(data.qts, "pcie-root-port", "hprp", 1167 "{'bus': 'rphptgt2', 'addr': '0.0' }"); 1168 qtest_qmp_device_add(data.qts, "pci-testdev", "hpnic", 1169 "{'bus': 'rphptgt3', 'addr': '0.0' }"); 1170 qtest_qmp_send(data.qts, "{'execute':'cont' }"); 1171 qtest_qmp_eventwait(data.qts, "RESUME"); 1172 1173 process_acpi_tables_noexit(&data); 1174 free_test_data(&data); 1175 1176 /* check that reboot/reset doesn't change any ACPI tables */ 1177 qtest_qmp_send(data.qts, "{'execute':'system_reset' }"); 1178 process_acpi_tables(&data); 1179 free_test_data(&data); 1180 } 1181 1182 static void test_acpi_q35_tcg_mmio64(void) 1183 { 1184 test_data data = { 1185 .machine = MACHINE_Q35, 1186 .variant = ".mmio64", 1187 .tcg_only = true, 1188 .required_struct_types = base_required_struct_types, 1189 .required_struct_types_len = ARRAY_SIZE(base_required_struct_types) 1190 }; 1191 1192 test_acpi_one("-m 128M,slots=1,maxmem=2G " 1193 "-cpu Opteron_G1 " 1194 "-object memory-backend-ram,id=ram0,size=128M " 1195 "-numa node,memdev=ram0 " 1196 "-device pci-testdev,membar=2G", 1197 &data); 1198 free_test_data(&data); 1199 } 1200 1201 static void test_acpi_piix4_tcg_cphp(void) 1202 { 1203 test_data data = {}; 1204 1205 data.machine = MACHINE_PC; 1206 data.variant = ".cphp"; 1207 test_acpi_one("-smp 2,cores=3,sockets=2,maxcpus=6" 1208 " -object memory-backend-ram,id=ram0,size=64M" 1209 " -object memory-backend-ram,id=ram1,size=64M" 1210 " -numa node,memdev=ram0 -numa node,memdev=ram1" 1211 " -numa dist,src=0,dst=1,val=21", 1212 &data); 1213 free_test_data(&data); 1214 } 1215 1216 static void test_acpi_q35_tcg_cphp(void) 1217 { 1218 test_data data = {}; 1219 1220 data.machine = MACHINE_Q35; 1221 data.variant = ".cphp"; 1222 test_acpi_one(" -smp 2,cores=3,sockets=2,maxcpus=6" 1223 " -object memory-backend-ram,id=ram0,size=64M" 1224 " -object memory-backend-ram,id=ram1,size=64M" 1225 " -numa node,memdev=ram0 -numa node,memdev=ram1" 1226 " -numa dist,src=0,dst=1,val=21", 1227 &data); 1228 free_test_data(&data); 1229 } 1230 1231 static uint8_t ipmi_required_struct_types[] = { 1232 0, 1, 3, 4, 16, 17, 19, 32, 38, 127 1233 }; 1234 1235 static void test_acpi_q35_tcg_ipmi(void) 1236 { 1237 test_data data = {}; 1238 1239 data.machine = MACHINE_Q35; 1240 data.variant = ".ipmibt"; 1241 data.required_struct_types = ipmi_required_struct_types; 1242 data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types); 1243 test_acpi_one("-device ipmi-bmc-sim,id=bmc0" 1244 " -device isa-ipmi-bt,bmc=bmc0", 1245 &data); 1246 free_test_data(&data); 1247 } 1248 1249 static void test_acpi_q35_tcg_smbus_ipmi(void) 1250 { 1251 test_data data = {}; 1252 1253 data.machine = MACHINE_Q35; 1254 data.variant = ".ipmismbus"; 1255 data.required_struct_types = ipmi_required_struct_types; 1256 data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types); 1257 test_acpi_one("-device ipmi-bmc-sim,id=bmc0" 1258 " -device smbus-ipmi,bmc=bmc0", 1259 &data); 1260 free_test_data(&data); 1261 } 1262 1263 static void test_acpi_piix4_tcg_ipmi(void) 1264 { 1265 test_data data = {}; 1266 1267 /* Supplying -machine accel argument overrides the default (qtest). 1268 * This is to make guest actually run. 1269 */ 1270 data.machine = MACHINE_PC; 1271 data.variant = ".ipmikcs"; 1272 data.required_struct_types = ipmi_required_struct_types; 1273 data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types); 1274 test_acpi_one("-device ipmi-bmc-sim,id=bmc0" 1275 " -device isa-ipmi-kcs,irq=0,bmc=bmc0", 1276 &data); 1277 free_test_data(&data); 1278 } 1279 1280 static void test_acpi_q35_tcg_memhp(void) 1281 { 1282 test_data data = {}; 1283 1284 data.machine = MACHINE_Q35; 1285 data.variant = ".memhp"; 1286 test_acpi_one(" -m 128,slots=3,maxmem=1G" 1287 " -object memory-backend-ram,id=ram0,size=64M" 1288 " -object memory-backend-ram,id=ram1,size=64M" 1289 " -numa node,memdev=ram0 -numa node,memdev=ram1" 1290 " -numa dist,src=0,dst=1,val=21", 1291 &data); 1292 free_test_data(&data); 1293 } 1294 1295 static void test_acpi_piix4_tcg_memhp(void) 1296 { 1297 test_data data = {}; 1298 1299 data.machine = MACHINE_PC; 1300 data.variant = ".memhp"; 1301 test_acpi_one(" -m 128,slots=3,maxmem=1G" 1302 " -object memory-backend-ram,id=ram0,size=64M" 1303 " -object memory-backend-ram,id=ram1,size=64M" 1304 " -numa node,memdev=ram0 -numa node,memdev=ram1" 1305 " -numa dist,src=0,dst=1,val=21", 1306 &data); 1307 free_test_data(&data); 1308 } 1309 1310 static void test_acpi_piix4_tcg_nosmm(void) 1311 { 1312 test_data data = {}; 1313 1314 data.machine = MACHINE_PC; 1315 data.variant = ".nosmm"; 1316 test_acpi_one("-machine smm=off", &data); 1317 free_test_data(&data); 1318 } 1319 1320 static void test_acpi_piix4_tcg_smm_compat(void) 1321 { 1322 test_data data = {}; 1323 1324 data.machine = MACHINE_PC; 1325 data.variant = ".smm-compat"; 1326 test_acpi_one("-global PIIX4_PM.smm-compat=on", &data); 1327 free_test_data(&data); 1328 } 1329 1330 static void test_acpi_piix4_tcg_smm_compat_nosmm(void) 1331 { 1332 test_data data = {}; 1333 1334 data.machine = MACHINE_PC; 1335 data.variant = ".smm-compat-nosmm"; 1336 test_acpi_one("-global PIIX4_PM.smm-compat=on -machine smm=off", &data); 1337 free_test_data(&data); 1338 } 1339 1340 static void test_acpi_piix4_tcg_nohpet(void) 1341 { 1342 test_data data = {}; 1343 1344 data.machine = MACHINE_PC; 1345 data.machine_param = ",hpet=off"; 1346 data.variant = ".nohpet"; 1347 test_acpi_one(NULL, &data); 1348 free_test_data(&data); 1349 } 1350 1351 static void test_acpi_q35_tcg_numamem(void) 1352 { 1353 test_data data = {}; 1354 1355 data.machine = MACHINE_Q35; 1356 data.variant = ".numamem"; 1357 test_acpi_one(" -object memory-backend-ram,id=ram0,size=128M" 1358 " -numa node -numa node,memdev=ram0", &data); 1359 free_test_data(&data); 1360 } 1361 1362 static void test_acpi_q35_kvm_xapic(void) 1363 { 1364 test_data data = {}; 1365 1366 data.machine = MACHINE_Q35; 1367 data.variant = ".xapic"; 1368 test_acpi_one(" -object memory-backend-ram,id=ram0,size=128M" 1369 " -numa node -numa node,memdev=ram0" 1370 " -machine kernel-irqchip=on -smp 1,maxcpus=288", &data); 1371 free_test_data(&data); 1372 } 1373 1374 static void test_acpi_q35_tcg_nosmm(void) 1375 { 1376 test_data data = {}; 1377 1378 data.machine = MACHINE_Q35; 1379 data.variant = ".nosmm"; 1380 test_acpi_one("-machine smm=off", &data); 1381 free_test_data(&data); 1382 } 1383 1384 static void test_acpi_q35_tcg_smm_compat(void) 1385 { 1386 test_data data = {}; 1387 1388 data.machine = MACHINE_Q35; 1389 data.variant = ".smm-compat"; 1390 test_acpi_one("-global ICH9-LPC.smm-compat=on", &data); 1391 free_test_data(&data); 1392 } 1393 1394 static void test_acpi_q35_tcg_smm_compat_nosmm(void) 1395 { 1396 test_data data = {}; 1397 1398 data.machine = MACHINE_Q35; 1399 data.variant = ".smm-compat-nosmm"; 1400 test_acpi_one("-global ICH9-LPC.smm-compat=on -machine smm=off", &data); 1401 free_test_data(&data); 1402 } 1403 1404 static void test_acpi_q35_tcg_nohpet(void) 1405 { 1406 test_data data = {}; 1407 1408 data.machine = MACHINE_Q35; 1409 data.machine_param = ",hpet=off"; 1410 data.variant = ".nohpet"; 1411 test_acpi_one(NULL, &data); 1412 free_test_data(&data); 1413 } 1414 1415 static void test_acpi_q35_kvm_dmar(void) 1416 { 1417 test_data data = {}; 1418 1419 data.machine = MACHINE_Q35; 1420 data.variant = ".dmar"; 1421 test_acpi_one("-machine kernel-irqchip=split -accel kvm" 1422 " -device intel-iommu,intremap=on,device-iotlb=on", &data); 1423 free_test_data(&data); 1424 } 1425 1426 static void test_acpi_q35_tcg_ivrs(void) 1427 { 1428 test_data data = {}; 1429 1430 data.machine = MACHINE_Q35; 1431 data.variant = ".ivrs"; 1432 data.tcg_only = true, 1433 test_acpi_one(" -device amd-iommu", &data); 1434 free_test_data(&data); 1435 } 1436 1437 static void test_acpi_piix4_tcg_numamem(void) 1438 { 1439 test_data data = {}; 1440 1441 data.machine = MACHINE_PC; 1442 data.variant = ".numamem"; 1443 test_acpi_one(" -object memory-backend-ram,id=ram0,size=128M" 1444 " -numa node -numa node,memdev=ram0", &data); 1445 free_test_data(&data); 1446 } 1447 1448 uint64_t tpm_tis_base_addr; 1449 1450 static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if, 1451 uint64_t base, enum TPMVersion tpm_version) 1452 { 1453 gchar *tmp_dir_name = g_strdup_printf("qemu-test_acpi_%s_tcg_%s.XXXXXX", 1454 machine, tpm_if); 1455 char *tmp_path = g_dir_make_tmp(tmp_dir_name, NULL); 1456 TPMTestState test; 1457 test_data data = {}; 1458 GThread *thread; 1459 const char *suffix = tpm_version == TPM_VERSION_2_0 ? "tpm2" : "tpm12"; 1460 char *args, *variant = g_strdup_printf(".%s.%s", tpm_if, suffix); 1461 1462 tpm_tis_base_addr = base; 1463 1464 module_call_init(MODULE_INIT_QOM); 1465 1466 test.addr = g_new0(SocketAddress, 1); 1467 test.addr->type = SOCKET_ADDRESS_TYPE_UNIX; 1468 test.addr->u.q_unix.path = g_build_filename(tmp_path, "sock", NULL); 1469 g_mutex_init(&test.data_mutex); 1470 g_cond_init(&test.data_cond); 1471 test.data_cond_signal = false; 1472 test.tpm_version = tpm_version; 1473 1474 thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test); 1475 tpm_emu_test_wait_cond(&test); 1476 1477 data.machine = machine; 1478 data.variant = variant; 1479 1480 args = g_strdup_printf( 1481 " -chardev socket,id=chr,path=%s" 1482 " -tpmdev emulator,id=dev,chardev=chr" 1483 " -device tpm-%s,tpmdev=dev", 1484 test.addr->u.q_unix.path, tpm_if); 1485 1486 test_acpi_one(args, &data); 1487 1488 g_thread_join(thread); 1489 g_unlink(test.addr->u.q_unix.path); 1490 qapi_free_SocketAddress(test.addr); 1491 g_rmdir(tmp_path); 1492 g_free(variant); 1493 g_free(tmp_path); 1494 g_free(tmp_dir_name); 1495 g_free(args); 1496 free_test_data(&data); 1497 } 1498 1499 static void test_acpi_q35_tcg_tpm2_tis(void) 1500 { 1501 test_acpi_tcg_tpm("q35", "tis", 0xFED40000, TPM_VERSION_2_0); 1502 } 1503 1504 static void test_acpi_q35_tcg_tpm12_tis(void) 1505 { 1506 test_acpi_tcg_tpm("q35", "tis", 0xFED40000, TPM_VERSION_1_2); 1507 } 1508 1509 static void test_acpi_tcg_dimm_pxm(const char *machine) 1510 { 1511 test_data data = {}; 1512 1513 data.machine = machine; 1514 data.variant = ".dimmpxm"; 1515 test_acpi_one(" -machine nvdimm=on,nvdimm-persistence=cpu" 1516 " -smp 4,sockets=4" 1517 " -m 128M,slots=3,maxmem=1G" 1518 " -object memory-backend-ram,id=ram0,size=32M" 1519 " -object memory-backend-ram,id=ram1,size=32M" 1520 " -object memory-backend-ram,id=ram2,size=32M" 1521 " -object memory-backend-ram,id=ram3,size=32M" 1522 " -numa node,memdev=ram0,nodeid=0" 1523 " -numa node,memdev=ram1,nodeid=1" 1524 " -numa node,memdev=ram2,nodeid=2" 1525 " -numa node,memdev=ram3,nodeid=3" 1526 " -numa cpu,node-id=0,socket-id=0" 1527 " -numa cpu,node-id=1,socket-id=1" 1528 " -numa cpu,node-id=2,socket-id=2" 1529 " -numa cpu,node-id=3,socket-id=3" 1530 " -object memory-backend-ram,id=ram4,size=128M" 1531 " -object memory-backend-ram,id=nvm0,size=128M" 1532 " -device pc-dimm,id=dimm0,memdev=ram4,node=1" 1533 " -device nvdimm,id=dimm1,memdev=nvm0,node=2", 1534 &data); 1535 free_test_data(&data); 1536 } 1537 1538 static void test_acpi_q35_tcg_dimm_pxm(void) 1539 { 1540 test_acpi_tcg_dimm_pxm(MACHINE_Q35); 1541 } 1542 1543 static void test_acpi_piix4_tcg_dimm_pxm(void) 1544 { 1545 test_acpi_tcg_dimm_pxm(MACHINE_PC); 1546 } 1547 1548 static void test_acpi_virt_tcg_memhp(void) 1549 { 1550 test_data data = { 1551 .machine = "virt", 1552 .tcg_only = true, 1553 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", 1554 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", 1555 .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", 1556 .ram_start = 0x40000000ULL, 1557 .scan_len = 256ULL * 1024 * 1024, 1558 }; 1559 1560 data.variant = ".memhp"; 1561 test_acpi_one(" -machine nvdimm=on" 1562 " -cpu cortex-a57" 1563 " -m 256M,slots=3,maxmem=1G" 1564 " -object memory-backend-ram,id=ram0,size=128M" 1565 " -object memory-backend-ram,id=ram1,size=128M" 1566 " -numa node,memdev=ram0 -numa node,memdev=ram1" 1567 " -numa dist,src=0,dst=1,val=21" 1568 " -object memory-backend-ram,id=ram2,size=128M" 1569 " -object memory-backend-ram,id=nvm0,size=128M" 1570 " -device pc-dimm,id=dimm0,memdev=ram2,node=0" 1571 " -device nvdimm,id=dimm1,memdev=nvm0,node=1", 1572 &data); 1573 1574 free_test_data(&data); 1575 1576 } 1577 1578 static void test_acpi_microvm_prepare(test_data *data) 1579 { 1580 data->machine = "microvm"; 1581 data->required_struct_types = NULL; /* no smbios */ 1582 data->required_struct_types_len = 0; 1583 data->blkdev = "virtio-blk-device"; 1584 } 1585 1586 static void test_acpi_microvm_tcg(void) 1587 { 1588 test_data data = {}; 1589 1590 test_acpi_microvm_prepare(&data); 1591 test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=off", 1592 &data); 1593 free_test_data(&data); 1594 } 1595 1596 static void test_acpi_microvm_usb_tcg(void) 1597 { 1598 test_data data = {}; 1599 1600 test_acpi_microvm_prepare(&data); 1601 data.variant = ".usb"; 1602 test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,usb=on,rtc=off", 1603 &data); 1604 free_test_data(&data); 1605 } 1606 1607 static void test_acpi_microvm_rtc_tcg(void) 1608 { 1609 test_data data = {}; 1610 1611 test_acpi_microvm_prepare(&data); 1612 data.variant = ".rtc"; 1613 test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=on", 1614 &data); 1615 free_test_data(&data); 1616 } 1617 1618 static void test_acpi_microvm_pcie_tcg(void) 1619 { 1620 test_data data = {}; 1621 1622 test_acpi_microvm_prepare(&data); 1623 data.variant = ".pcie"; 1624 data.tcg_only = true; /* need constant host-phys-bits */ 1625 test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=off,pcie=on", 1626 &data); 1627 free_test_data(&data); 1628 } 1629 1630 static void test_acpi_microvm_ioapic2_tcg(void) 1631 { 1632 test_data data = {}; 1633 1634 test_acpi_microvm_prepare(&data); 1635 data.variant = ".ioapic2"; 1636 test_acpi_one(" -machine microvm,acpi=on,ioapic2=on,rtc=off", 1637 &data); 1638 free_test_data(&data); 1639 } 1640 1641 static void test_acpi_virt_tcg_numamem(void) 1642 { 1643 test_data data = { 1644 .machine = "virt", 1645 .tcg_only = true, 1646 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", 1647 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", 1648 .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", 1649 .ram_start = 0x40000000ULL, 1650 .scan_len = 128ULL * 1024 * 1024, 1651 }; 1652 1653 data.variant = ".numamem"; 1654 test_acpi_one(" -cpu cortex-a57" 1655 " -object memory-backend-ram,id=ram0,size=128M" 1656 " -numa node,memdev=ram0", 1657 &data); 1658 1659 free_test_data(&data); 1660 1661 } 1662 1663 static void test_acpi_virt_tcg_pxb(void) 1664 { 1665 test_data data = { 1666 .machine = "virt", 1667 .tcg_only = true, 1668 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", 1669 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", 1670 .ram_start = 0x40000000ULL, 1671 .scan_len = 128ULL * 1024 * 1024, 1672 }; 1673 /* 1674 * While using -cdrom, the cdrom would auto plugged into pxb-pcie, 1675 * the reason is the bus of pxb-pcie is also root bus, it would lead 1676 * to the error only PCI/PCIE bridge could plug onto pxb. 1677 * Therefore,thr cdrom is defined and plugged onto the scsi controller 1678 * to solve the conflicts. 1679 */ 1680 data.variant = ".pxb"; 1681 test_acpi_one(" -device pcie-root-port,chassis=1,id=pci.1" 1682 " -device virtio-scsi-pci,id=scsi0,bus=pci.1" 1683 " -drive file=" 1684 "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2," 1685 "if=none,media=cdrom,id=drive-scsi0-0-0-1,readonly=on" 1686 " -device scsi-cd,bus=scsi0.0,scsi-id=0," 1687 "drive=drive-scsi0-0-0-1,id=scsi0-0-0-1,bootindex=1" 1688 " -cpu cortex-a57" 1689 " -device pxb-pcie,bus_nr=128", 1690 &data); 1691 1692 free_test_data(&data); 1693 } 1694 1695 static void test_acpi_tcg_acpi_hmat(const char *machine) 1696 { 1697 test_data data = {}; 1698 1699 data.machine = machine; 1700 data.variant = ".acpihmat"; 1701 test_acpi_one(" -machine hmat=on" 1702 " -smp 2,sockets=2" 1703 " -m 128M,slots=2,maxmem=1G" 1704 " -object memory-backend-ram,size=64M,id=m0" 1705 " -object memory-backend-ram,size=64M,id=m1" 1706 " -numa node,nodeid=0,memdev=m0" 1707 " -numa node,nodeid=1,memdev=m1,initiator=0" 1708 " -numa cpu,node-id=0,socket-id=0" 1709 " -numa cpu,node-id=0,socket-id=1" 1710 " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," 1711 "data-type=access-latency,latency=1" 1712 " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," 1713 "data-type=access-bandwidth,bandwidth=65534M" 1714 " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," 1715 "data-type=access-latency,latency=65534" 1716 " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," 1717 "data-type=access-bandwidth,bandwidth=32767M" 1718 " -numa hmat-cache,node-id=0,size=10K,level=1," 1719 "associativity=direct,policy=write-back,line=8" 1720 " -numa hmat-cache,node-id=1,size=10K,level=1," 1721 "associativity=direct,policy=write-back,line=8", 1722 &data); 1723 free_test_data(&data); 1724 } 1725 1726 static void test_acpi_q35_tcg_acpi_hmat(void) 1727 { 1728 test_acpi_tcg_acpi_hmat(MACHINE_Q35); 1729 } 1730 1731 static void test_acpi_piix4_tcg_acpi_hmat(void) 1732 { 1733 test_acpi_tcg_acpi_hmat(MACHINE_PC); 1734 } 1735 1736 static void test_acpi_virt_tcg_acpi_hmat(void) 1737 { 1738 test_data data = { 1739 .machine = "virt", 1740 .tcg_only = true, 1741 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", 1742 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", 1743 .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", 1744 .ram_start = 0x40000000ULL, 1745 .scan_len = 128ULL * 1024 * 1024, 1746 }; 1747 1748 data.variant = ".acpihmatvirt"; 1749 1750 test_acpi_one(" -machine hmat=on" 1751 " -cpu cortex-a57" 1752 " -smp 4,sockets=2" 1753 " -m 384M" 1754 " -object memory-backend-ram,size=128M,id=ram0" 1755 " -object memory-backend-ram,size=128M,id=ram1" 1756 " -object memory-backend-ram,size=128M,id=ram2" 1757 " -numa node,nodeid=0,memdev=ram0" 1758 " -numa node,nodeid=1,memdev=ram1" 1759 " -numa node,nodeid=2,memdev=ram2" 1760 " -numa cpu,node-id=0,socket-id=0" 1761 " -numa cpu,node-id=0,socket-id=0" 1762 " -numa cpu,node-id=1,socket-id=1" 1763 " -numa cpu,node-id=1,socket-id=1" 1764 " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," 1765 "data-type=access-latency,latency=10" 1766 " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," 1767 "data-type=access-bandwidth,bandwidth=10485760" 1768 " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," 1769 "data-type=access-latency,latency=20" 1770 " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," 1771 "data-type=access-bandwidth,bandwidth=5242880" 1772 " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," 1773 "data-type=access-latency,latency=30" 1774 " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," 1775 "data-type=access-bandwidth,bandwidth=1048576" 1776 " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," 1777 "data-type=access-latency,latency=20" 1778 " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," 1779 "data-type=access-bandwidth,bandwidth=5242880" 1780 " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," 1781 "data-type=access-latency,latency=10" 1782 " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," 1783 "data-type=access-bandwidth,bandwidth=10485760" 1784 " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," 1785 "data-type=access-latency,latency=30" 1786 " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," 1787 "data-type=access-bandwidth,bandwidth=1048576", 1788 &data); 1789 1790 free_test_data(&data); 1791 } 1792 1793 static void test_acpi_q35_tcg_acpi_hmat_noinitiator(void) 1794 { 1795 test_data data = {}; 1796 1797 data.machine = MACHINE_Q35; 1798 data.variant = ".acpihmat-noinitiator"; 1799 test_acpi_one(" -machine hmat=on" 1800 " -smp 4,sockets=2" 1801 " -m 128M" 1802 " -object memory-backend-ram,size=32M,id=ram0" 1803 " -object memory-backend-ram,size=32M,id=ram1" 1804 " -object memory-backend-ram,size=64M,id=ram2" 1805 " -numa node,nodeid=0,memdev=ram0" 1806 " -numa node,nodeid=1,memdev=ram1" 1807 " -numa node,nodeid=2,memdev=ram2" 1808 " -numa cpu,node-id=0,socket-id=0" 1809 " -numa cpu,node-id=0,socket-id=0" 1810 " -numa cpu,node-id=1,socket-id=1" 1811 " -numa cpu,node-id=1,socket-id=1" 1812 " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," 1813 "data-type=access-latency,latency=10" 1814 " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," 1815 "data-type=access-bandwidth,bandwidth=10485760" 1816 " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," 1817 "data-type=access-latency,latency=20" 1818 " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," 1819 "data-type=access-bandwidth,bandwidth=5242880" 1820 " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," 1821 "data-type=access-latency,latency=30" 1822 " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," 1823 "data-type=access-bandwidth,bandwidth=1048576" 1824 " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," 1825 "data-type=access-latency,latency=20" 1826 " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," 1827 "data-type=access-bandwidth,bandwidth=5242880" 1828 " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," 1829 "data-type=access-latency,latency=10" 1830 " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," 1831 "data-type=access-bandwidth,bandwidth=10485760" 1832 " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," 1833 "data-type=access-latency,latency=30" 1834 " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," 1835 "data-type=access-bandwidth,bandwidth=1048576", 1836 &data); 1837 free_test_data(&data); 1838 } 1839 1840 #ifdef CONFIG_POSIX 1841 static void test_acpi_erst(const char *machine) 1842 { 1843 gchar *tmp_path = g_dir_make_tmp("qemu-test-erst.XXXXXX", NULL); 1844 gchar *params; 1845 test_data data = {}; 1846 1847 data.machine = machine; 1848 data.variant = ".acpierst"; 1849 params = g_strdup_printf( 1850 " -object memory-backend-file,id=erstnvram," 1851 "mem-path=%s,size=0x10000,share=on" 1852 " -device acpi-erst,memdev=erstnvram", tmp_path); 1853 test_acpi_one(params, &data); 1854 free_test_data(&data); 1855 g_free(params); 1856 g_assert(g_rmdir(tmp_path) == 0); 1857 g_free(tmp_path); 1858 } 1859 1860 static void test_acpi_piix4_acpi_erst(void) 1861 { 1862 test_acpi_erst(MACHINE_PC); 1863 } 1864 1865 static void test_acpi_q35_acpi_erst(void) 1866 { 1867 test_acpi_erst(MACHINE_Q35); 1868 } 1869 1870 static void test_acpi_microvm_acpi_erst(void) 1871 { 1872 gchar *tmp_path = g_dir_make_tmp("qemu-test-erst.XXXXXX", NULL); 1873 gchar *params; 1874 test_data data = {}; 1875 1876 test_acpi_microvm_prepare(&data); 1877 data.variant = ".pcie"; 1878 data.tcg_only = true; /* need constant host-phys-bits */ 1879 params = g_strdup_printf(" -machine microvm," 1880 "acpi=on,ioapic2=off,rtc=off,pcie=on" 1881 " -object memory-backend-file,id=erstnvram," 1882 "mem-path=%s,size=0x10000,share=on" 1883 " -device acpi-erst,memdev=erstnvram", tmp_path); 1884 test_acpi_one(params, &data); 1885 g_free(params); 1886 g_assert(g_rmdir(tmp_path) == 0); 1887 g_free(tmp_path); 1888 free_test_data(&data); 1889 } 1890 #endif /* CONFIG_POSIX */ 1891 1892 static void test_acpi_virt_tcg(void) 1893 { 1894 test_data data = { 1895 .machine = "virt", 1896 .tcg_only = true, 1897 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", 1898 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", 1899 .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", 1900 .ram_start = 0x40000000ULL, 1901 .scan_len = 128ULL * 1024 * 1024, 1902 }; 1903 1904 data.smbios_cpu_max_speed = 2900; 1905 data.smbios_cpu_curr_speed = 2700; 1906 test_acpi_one("-cpu cortex-a57 " 1907 "-smbios type=4,max-speed=2900,current-speed=2700", &data); 1908 free_test_data(&data); 1909 } 1910 1911 static void test_acpi_virt_tcg_topology(void) 1912 { 1913 test_data data = { 1914 .machine = "virt", 1915 .variant = ".topology", 1916 .tcg_only = true, 1917 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", 1918 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", 1919 .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", 1920 .ram_start = 0x40000000ULL, 1921 .scan_len = 128ULL * 1024 * 1024, 1922 }; 1923 1924 test_acpi_one("-cpu cortex-a57 " 1925 "-smp sockets=1,clusters=2,cores=2,threads=2", &data); 1926 free_test_data(&data); 1927 } 1928 1929 static void test_acpi_q35_viot(void) 1930 { 1931 test_data data = { 1932 .machine = MACHINE_Q35, 1933 .variant = ".viot", 1934 }; 1935 1936 /* 1937 * To keep things interesting, two buses bypass the IOMMU. 1938 * VIOT should only describes the other two buses. 1939 */ 1940 test_acpi_one("-machine default_bus_bypass_iommu=on " 1941 "-device virtio-iommu-pci " 1942 "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 " 1943 "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on " 1944 "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0", 1945 &data); 1946 free_test_data(&data); 1947 } 1948 1949 #ifdef CONFIG_POSIX 1950 static void test_acpi_q35_cxl(void) 1951 { 1952 gchar *tmp_path = g_dir_make_tmp("qemu-test-cxl.XXXXXX", NULL); 1953 gchar *params; 1954 1955 test_data data = { 1956 .machine = MACHINE_Q35, 1957 .variant = ".cxl", 1958 }; 1959 /* 1960 * A complex CXL setup. 1961 */ 1962 params = g_strdup_printf(" -machine cxl=on" 1963 " -object memory-backend-file,id=cxl-mem1,mem-path=%s,size=256M" 1964 " -object memory-backend-file,id=cxl-mem2,mem-path=%s,size=256M" 1965 " -object memory-backend-file,id=cxl-mem3,mem-path=%s,size=256M" 1966 " -object memory-backend-file,id=cxl-mem4,mem-path=%s,size=256M" 1967 " -object memory-backend-file,id=lsa1,mem-path=%s,size=256M" 1968 " -object memory-backend-file,id=lsa2,mem-path=%s,size=256M" 1969 " -object memory-backend-file,id=lsa3,mem-path=%s,size=256M" 1970 " -object memory-backend-file,id=lsa4,mem-path=%s,size=256M" 1971 " -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1" 1972 " -device pxb-cxl,bus_nr=222,bus=pcie.0,id=cxl.2" 1973 " -device cxl-rp,port=0,bus=cxl.1,id=rp1,chassis=0,slot=2" 1974 " -device cxl-type3,bus=rp1,persistent-memdev=cxl-mem1,lsa=lsa1" 1975 " -device cxl-rp,port=1,bus=cxl.1,id=rp2,chassis=0,slot=3" 1976 " -device cxl-type3,bus=rp2,persistent-memdev=cxl-mem2,lsa=lsa2" 1977 " -device cxl-rp,port=0,bus=cxl.2,id=rp3,chassis=0,slot=5" 1978 " -device cxl-type3,bus=rp3,persistent-memdev=cxl-mem3,lsa=lsa3" 1979 " -device cxl-rp,port=1,bus=cxl.2,id=rp4,chassis=0,slot=6" 1980 " -device cxl-type3,bus=rp4,persistent-memdev=cxl-mem4,lsa=lsa4" 1981 " -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=8k," 1982 "cxl-fmw.1.targets.0=cxl.1,cxl-fmw.1.targets.1=cxl.2,cxl-fmw.1.size=4G,cxl-fmw.1.interleave-granularity=8k", 1983 tmp_path, tmp_path, tmp_path, tmp_path, 1984 tmp_path, tmp_path, tmp_path, tmp_path); 1985 test_acpi_one(params, &data); 1986 1987 g_free(params); 1988 g_assert(g_rmdir(tmp_path) == 0); 1989 g_free(tmp_path); 1990 free_test_data(&data); 1991 } 1992 #endif /* CONFIG_POSIX */ 1993 1994 static void test_acpi_virt_viot(void) 1995 { 1996 test_data data = { 1997 .machine = "virt", 1998 .tcg_only = true, 1999 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", 2000 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", 2001 .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", 2002 .ram_start = 0x40000000ULL, 2003 .scan_len = 128ULL * 1024 * 1024, 2004 }; 2005 2006 test_acpi_one("-cpu cortex-a57 " 2007 "-device virtio-iommu-pci", &data); 2008 free_test_data(&data); 2009 } 2010 2011 #ifndef _WIN32 2012 # define DEV_NULL "/dev/null" 2013 #else 2014 # define DEV_NULL "nul" 2015 #endif 2016 2017 static void test_acpi_q35_slic(void) 2018 { 2019 test_data data = { 2020 .machine = MACHINE_Q35, 2021 .variant = ".slic", 2022 }; 2023 2024 test_acpi_one("-acpitable sig=SLIC,oem_id=\"CRASH \",oem_table_id=ME," 2025 "oem_rev=00002210,asl_compiler_id=qemu," 2026 "asl_compiler_rev=00000000,data=" DEV_NULL, 2027 &data); 2028 free_test_data(&data); 2029 } 2030 2031 static void test_acpi_q35_applesmc(void) 2032 { 2033 test_data data = { 2034 .machine = MACHINE_Q35, 2035 .variant = ".applesmc", 2036 }; 2037 2038 /* supply fake 64-byte OSK to silence missing key warning */ 2039 test_acpi_one("-device isa-applesmc,osk=any64characterfakeoskisenough" 2040 "topreventinvalidkeywarningsonstderr", &data); 2041 free_test_data(&data); 2042 } 2043 2044 static void test_acpi_q35_pvpanic_isa(void) 2045 { 2046 test_data data = { 2047 .machine = MACHINE_Q35, 2048 .variant = ".pvpanic-isa", 2049 }; 2050 2051 test_acpi_one("-device pvpanic", &data); 2052 free_test_data(&data); 2053 } 2054 2055 static void test_oem_fields(test_data *data) 2056 { 2057 int i; 2058 2059 for (i = 0; i < data->tables->len; ++i) { 2060 AcpiSdtTable *sdt; 2061 2062 sdt = &g_array_index(data->tables, AcpiSdtTable, i); 2063 /* FACS doesn't have OEMID and OEMTABLEID fields */ 2064 if (compare_signature(sdt, "FACS")) { 2065 continue; 2066 } 2067 2068 g_assert(strncmp((char *)sdt->aml + 10, OEM_ID, 6) == 0); 2069 g_assert(strncmp((char *)sdt->aml + 16, OEM_TABLE_ID, 8) == 0); 2070 } 2071 } 2072 2073 static void test_acpi_piix4_oem_fields(void) 2074 { 2075 char *args; 2076 test_data data = {}; 2077 2078 data.machine = MACHINE_PC; 2079 data.required_struct_types = base_required_struct_types; 2080 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 2081 2082 args = test_acpi_create_args(&data, OEM_TEST_ARGS); 2083 data.qts = qtest_init(args); 2084 test_acpi_load_tables(&data); 2085 test_oem_fields(&data); 2086 qtest_quit(data.qts); 2087 free_test_data(&data); 2088 g_free(args); 2089 } 2090 2091 static void test_acpi_q35_oem_fields(void) 2092 { 2093 char *args; 2094 test_data data = {}; 2095 2096 data.machine = MACHINE_Q35; 2097 data.required_struct_types = base_required_struct_types; 2098 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); 2099 2100 args = test_acpi_create_args(&data, OEM_TEST_ARGS); 2101 data.qts = qtest_init(args); 2102 test_acpi_load_tables(&data); 2103 test_oem_fields(&data); 2104 qtest_quit(data.qts); 2105 free_test_data(&data); 2106 g_free(args); 2107 } 2108 2109 static void test_acpi_microvm_oem_fields(void) 2110 { 2111 test_data data = {}; 2112 char *args; 2113 2114 test_acpi_microvm_prepare(&data); 2115 2116 args = test_acpi_create_args(&data, 2117 OEM_TEST_ARGS",acpi=on"); 2118 data.qts = qtest_init(args); 2119 test_acpi_load_tables(&data); 2120 test_oem_fields(&data); 2121 qtest_quit(data.qts); 2122 free_test_data(&data); 2123 g_free(args); 2124 } 2125 2126 static void test_acpi_virt_oem_fields(void) 2127 { 2128 test_data data = { 2129 .machine = "virt", 2130 .tcg_only = true, 2131 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", 2132 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", 2133 .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", 2134 .ram_start = 0x40000000ULL, 2135 .scan_len = 128ULL * 1024 * 1024, 2136 }; 2137 char *args; 2138 2139 args = test_acpi_create_args(&data, "-cpu cortex-a57 "OEM_TEST_ARGS); 2140 data.qts = qtest_init(args); 2141 test_acpi_load_tables(&data); 2142 test_oem_fields(&data); 2143 qtest_quit(data.qts); 2144 free_test_data(&data); 2145 g_free(args); 2146 } 2147 2148 2149 int main(int argc, char *argv[]) 2150 { 2151 const char *arch = qtest_get_arch(); 2152 bool has_kvm, has_tcg; 2153 char *v_env = getenv("V"); 2154 int ret; 2155 2156 if (v_env) { 2157 verbosity_level = atoi(v_env); 2158 } 2159 2160 g_test_init(&argc, &argv, NULL); 2161 2162 has_kvm = qtest_has_accel("kvm"); 2163 has_tcg = qtest_has_accel("tcg"); 2164 2165 if (!has_tcg && !has_kvm) { 2166 g_test_skip("No KVM or TCG accelerator available"); 2167 return 0; 2168 } 2169 2170 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { 2171 ret = boot_sector_init(disk); 2172 if (ret) { 2173 return ret; 2174 } 2175 if (qtest_has_machine(MACHINE_PC)) { 2176 qtest_add_func("acpi/piix4", test_acpi_piix4_tcg); 2177 qtest_add_func("acpi/piix4/oem-fields", test_acpi_piix4_oem_fields); 2178 qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge); 2179 qtest_add_func("acpi/piix4/pci-hotplug/no_root_hotplug", 2180 test_acpi_piix4_no_root_hotplug); 2181 qtest_add_func("acpi/piix4/pci-hotplug/no_bridge_hotplug", 2182 test_acpi_piix4_no_bridge_hotplug); 2183 qtest_add_func("acpi/piix4/pci-hotplug/off", 2184 test_acpi_piix4_no_acpi_pci_hotplug); 2185 qtest_add_func("acpi/piix4/ipmi", test_acpi_piix4_tcg_ipmi); 2186 qtest_add_func("acpi/piix4/cpuhp", test_acpi_piix4_tcg_cphp); 2187 qtest_add_func("acpi/piix4/numamem", test_acpi_piix4_tcg_numamem); 2188 qtest_add_func("acpi/piix4/nosmm", test_acpi_piix4_tcg_nosmm); 2189 qtest_add_func("acpi/piix4/smm-compat", 2190 test_acpi_piix4_tcg_smm_compat); 2191 qtest_add_func("acpi/piix4/smm-compat-nosmm", 2192 test_acpi_piix4_tcg_smm_compat_nosmm); 2193 qtest_add_func("acpi/piix4/nohpet", test_acpi_piix4_tcg_nohpet); 2194 2195 /* i386 does not support memory hotplug */ 2196 if (strcmp(arch, "i386")) { 2197 qtest_add_func("acpi/piix4/memhp", test_acpi_piix4_tcg_memhp); 2198 qtest_add_func("acpi/piix4/dimmpxm", 2199 test_acpi_piix4_tcg_dimm_pxm); 2200 qtest_add_func("acpi/piix4/acpihmat", 2201 test_acpi_piix4_tcg_acpi_hmat); 2202 } 2203 #ifdef CONFIG_POSIX 2204 qtest_add_func("acpi/piix4/acpierst", test_acpi_piix4_acpi_erst); 2205 #endif 2206 } 2207 if (qtest_has_machine(MACHINE_Q35)) { 2208 qtest_add_func("acpi/q35", test_acpi_q35_tcg); 2209 qtest_add_func("acpi/q35/oem-fields", test_acpi_q35_oem_fields); 2210 if (tpm_model_is_available("-machine q35", "tpm-tis")) { 2211 qtest_add_func("acpi/q35/tpm2-tis", test_acpi_q35_tcg_tpm2_tis); 2212 qtest_add_func("acpi/q35/tpm12-tis", 2213 test_acpi_q35_tcg_tpm12_tis); 2214 } 2215 qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge); 2216 qtest_add_func("acpi/q35/no-acpi-hotplug", 2217 test_acpi_q35_tcg_no_acpi_hotplug); 2218 qtest_add_func("acpi/q35/multif-bridge", 2219 test_acpi_q35_multif_bridge); 2220 qtest_add_func("acpi/q35/ipmi", test_acpi_q35_tcg_ipmi); 2221 qtest_add_func("acpi/q35/smbus/ipmi", test_acpi_q35_tcg_smbus_ipmi); 2222 qtest_add_func("acpi/q35/cpuhp", test_acpi_q35_tcg_cphp); 2223 qtest_add_func("acpi/q35/numamem", test_acpi_q35_tcg_numamem); 2224 qtest_add_func("acpi/q35/nosmm", test_acpi_q35_tcg_nosmm); 2225 qtest_add_func("acpi/q35/smm-compat", 2226 test_acpi_q35_tcg_smm_compat); 2227 qtest_add_func("acpi/q35/smm-compat-nosmm", 2228 test_acpi_q35_tcg_smm_compat_nosmm); 2229 qtest_add_func("acpi/q35/nohpet", test_acpi_q35_tcg_nohpet); 2230 qtest_add_func("acpi/q35/acpihmat-noinitiator", 2231 test_acpi_q35_tcg_acpi_hmat_noinitiator); 2232 2233 /* i386 does not support memory hotplug */ 2234 if (strcmp(arch, "i386")) { 2235 qtest_add_func("acpi/q35/memhp", test_acpi_q35_tcg_memhp); 2236 qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm); 2237 qtest_add_func("acpi/q35/acpihmat", 2238 test_acpi_q35_tcg_acpi_hmat); 2239 qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64); 2240 } 2241 #ifdef CONFIG_POSIX 2242 qtest_add_func("acpi/q35/acpierst", test_acpi_q35_acpi_erst); 2243 #endif 2244 qtest_add_func("acpi/q35/applesmc", test_acpi_q35_applesmc); 2245 qtest_add_func("acpi/q35/pvpanic-isa", test_acpi_q35_pvpanic_isa); 2246 if (has_tcg) { 2247 qtest_add_func("acpi/q35/ivrs", test_acpi_q35_tcg_ivrs); 2248 } 2249 if (has_kvm) { 2250 qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic); 2251 qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar); 2252 qtest_add_func("acpi/q35/type4-count", 2253 test_acpi_q35_tcg_type4_count); 2254 qtest_add_func("acpi/q35/core-count", 2255 test_acpi_q35_tcg_core_count); 2256 qtest_add_func("acpi/q35/core-count2", 2257 test_acpi_q35_tcg_core_count2); 2258 qtest_add_func("acpi/q35/thread-count", 2259 test_acpi_q35_tcg_thread_count); 2260 qtest_add_func("acpi/q35/thread-count2", 2261 test_acpi_q35_tcg_thread_count2); 2262 } 2263 if (qtest_has_device("virtio-iommu-pci")) { 2264 qtest_add_func("acpi/q35/viot", test_acpi_q35_viot); 2265 } 2266 #ifdef CONFIG_POSIX 2267 qtest_add_func("acpi/q35/cxl", test_acpi_q35_cxl); 2268 #endif 2269 qtest_add_func("acpi/q35/slic", test_acpi_q35_slic); 2270 } 2271 if (qtest_has_machine("microvm")) { 2272 qtest_add_func("acpi/microvm", test_acpi_microvm_tcg); 2273 qtest_add_func("acpi/microvm/usb", test_acpi_microvm_usb_tcg); 2274 qtest_add_func("acpi/microvm/rtc", test_acpi_microvm_rtc_tcg); 2275 qtest_add_func("acpi/microvm/ioapic2", 2276 test_acpi_microvm_ioapic2_tcg); 2277 qtest_add_func("acpi/microvm/oem-fields", 2278 test_acpi_microvm_oem_fields); 2279 if (has_tcg) { 2280 if (strcmp(arch, "x86_64") == 0) { 2281 qtest_add_func("acpi/microvm/pcie", 2282 test_acpi_microvm_pcie_tcg); 2283 #ifdef CONFIG_POSIX 2284 qtest_add_func("acpi/microvm/acpierst", 2285 test_acpi_microvm_acpi_erst); 2286 #endif 2287 } 2288 } 2289 } 2290 } else if (strcmp(arch, "aarch64") == 0) { 2291 if (has_tcg && qtest_has_device("virtio-blk-pci")) { 2292 qtest_add_func("acpi/virt", test_acpi_virt_tcg); 2293 qtest_add_func("acpi/virt/acpihmatvirt", 2294 test_acpi_virt_tcg_acpi_hmat); 2295 qtest_add_func("acpi/virt/topology", test_acpi_virt_tcg_topology); 2296 qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem); 2297 qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp); 2298 qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb); 2299 qtest_add_func("acpi/virt/oem-fields", test_acpi_virt_oem_fields); 2300 if (qtest_has_device("virtio-iommu-pci")) { 2301 qtest_add_func("acpi/virt/viot", test_acpi_virt_viot); 2302 } 2303 } 2304 } 2305 ret = g_test_run(); 2306 boot_sector_cleanup(disk); 2307 return ret; 2308 } 2309