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