- Replace global_qtest in some tests

- Exit boot-serial-test loop if child dies
 - Sanitize verbose output in biot-tables-test
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJcF8nnAAoJEC7Z13T+cC21bGsP/RyyidCAs3/QAahL0O3UVjMP
 Md9CgtUUl3swpKPoKyFXmyQGAfvfPKjAyQP0ESlxcQEAFgcr9MrX2OvGQCHSerUV
 XtLB9k8d4vuSQn4diAVTTUU/iRZWstZGR5gkjXidBroXtYOLG8nO1MSPb0/pOH3l
 osMHg+ItNPzTjr6kzaM/D5TXZFslMMJ0mriT5ayPHuBsK1dSerpSg6SSswvcOuUR
 ZlhlWi4eNxTqO06uqv43AolOO8w5O12jgvtPxRiZw4j3Mvw8MPO2ZEB2bPlNjJ52
 SrO8Tl3Tvx9SsUwv31oBKcHMf7xGePqErE6wgBBmORB67MbLPPSGL2VVADxoMI1u
 n42bYwtLs0aAWfyXmgvUPScP2qRTwN7KQ5ETPDQNpov0ctUWi2O7NJXpkQzyz8WO
 +bv4HYZFTQzUxaW4SnUP4h6XBgMWZl7zQkEl4oUNIBiacWrq+I/793I66hiFPTtX
 o7j059HUqHYd3hETYX3GiScXBuHAdhXknhKEO8fSveBYMb0wPC9DfYkKL4c7gxfJ
 p5jU9DBNn2JolCMttvCJsfHCmxcG2wwzBElxW2wCnKgMa3nuQPvBjxr0x3FKb0r8
 f30pbnisNKowHG1VQXKm6gpJPOovA/JpIcA47egCqxuAWjSILEKpf169Y1HTtNQW
 nZnBah35LEdcibdyTao1
 =cz57
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2018-12-17' into staging

- Replace global_qtest in some tests
- Exit boot-serial-test loop if child dies
- Sanitize verbose output in biot-tables-test

# gpg: Signature made Mon 17 Dec 2018 16:08:07 GMT
# gpg:                using RSA key 2ED9D774FE702DB5
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>"
# gpg:                 aka "Thomas Huth <thuth@redhat.com>"
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>"
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>"
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* remotes/huth-gitlab/tags/pull-request-2018-12-17:
  tests/bios-tables-test: Sanitize test verbose output
  tests: acpi: remove not used ACPI_READ_GENERIC_ADDRESS macro
  tests: Exit boot-serial-test loop if child dies
  tests/pxe: Make test independent of global_qtest
  tests/prom-env: Make test independent of global_qtest
  tests/machine-none: Make test independent of global_qtest
  tests/test-filter: Make tests independent of global_qtest
  tests/boot-serial: Get rid of global_qtest variable
  tests/pvpanic: Make the pvpanic test independent of global_qtest
  tests/vmgenid: Make test independent of global_qtest
  tests/acpi-utils: Drop dependence on global_qtest
  ivshmem-test: Drop dependence on global_qtest
  tests/libqos/pci: Make PCI access functions independent of global_qtest

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-12-18 14:31:06 +00:00
commit e85c577158
16 changed files with 257 additions and 227 deletions

View File

@ -32,7 +32,7 @@ uint8_t acpi_calc_checksum(const uint8_t *data, int len)
return sum; return sum;
} }
uint32_t acpi_find_rsdp_address(void) uint32_t acpi_find_rsdp_address(QTestState *qts)
{ {
uint32_t off; uint32_t off;
@ -42,7 +42,7 @@ uint32_t acpi_find_rsdp_address(void)
int i; int i;
for (i = 0; i < sizeof sig - 1; ++i) { for (i = 0; i < sizeof sig - 1; ++i) {
sig[i] = readb(off + i); sig[i] = qtest_readb(qts, off + i);
} }
if (!memcmp(sig, "RSD PTR ", sizeof sig)) { if (!memcmp(sig, "RSD PTR ", sizeof sig)) {
@ -52,14 +52,15 @@ uint32_t acpi_find_rsdp_address(void)
return off; return off;
} }
void acpi_parse_rsdp_table(uint32_t addr, AcpiRsdpDescriptor *rsdp_table) void acpi_parse_rsdp_table(QTestState *qts, uint32_t addr,
AcpiRsdpDescriptor *rsdp_table)
{ {
ACPI_READ_FIELD(rsdp_table->signature, addr); ACPI_READ_FIELD(qts, rsdp_table->signature, addr);
ACPI_ASSERT_CMP64(rsdp_table->signature, "RSD PTR "); ACPI_ASSERT_CMP64(rsdp_table->signature, "RSD PTR ");
ACPI_READ_FIELD(rsdp_table->checksum, addr); ACPI_READ_FIELD(qts, rsdp_table->checksum, addr);
ACPI_READ_ARRAY(rsdp_table->oem_id, addr); ACPI_READ_ARRAY(qts, rsdp_table->oem_id, addr);
ACPI_READ_FIELD(rsdp_table->revision, addr); ACPI_READ_FIELD(qts, rsdp_table->revision, addr);
ACPI_READ_FIELD(rsdp_table->rsdt_physical_address, addr); ACPI_READ_FIELD(qts, rsdp_table->rsdt_physical_address, addr);
ACPI_READ_FIELD(rsdp_table->length, addr); ACPI_READ_FIELD(qts, rsdp_table->length, addr);
} }

View File

@ -28,34 +28,34 @@ typedef struct {
bool tmp_files_retain; /* do not delete the temp asl/aml */ bool tmp_files_retain; /* do not delete the temp asl/aml */
} AcpiSdtTable; } AcpiSdtTable;
#define ACPI_READ_FIELD(field, addr) \ #define ACPI_READ_FIELD(qts, field, addr) \
do { \ do { \
memread(addr, &field, sizeof(field)); \ qtest_memread(qts, addr, &field, sizeof(field)); \
addr += sizeof(field); \ addr += sizeof(field); \
} while (0) } while (0)
#define ACPI_READ_ARRAY_PTR(arr, length, addr) \ #define ACPI_READ_ARRAY_PTR(qts, arr, length, addr) \
do { \ do { \
int idx; \ int idx; \
for (idx = 0; idx < length; ++idx) { \ for (idx = 0; idx < length; ++idx) { \
ACPI_READ_FIELD(arr[idx], addr); \ ACPI_READ_FIELD(qts, arr[idx], addr); \
} \ } \
} while (0) } while (0)
#define ACPI_READ_ARRAY(arr, addr) \ #define ACPI_READ_ARRAY(qts, arr, addr) \
ACPI_READ_ARRAY_PTR(arr, sizeof(arr) / sizeof(arr[0]), addr) ACPI_READ_ARRAY_PTR(qts, arr, sizeof(arr) / sizeof(arr[0]), addr)
#define ACPI_READ_TABLE_HEADER(table, addr) \ #define ACPI_READ_TABLE_HEADER(qts, table, addr) \
do { \ do { \
ACPI_READ_FIELD((table)->signature, addr); \ ACPI_READ_FIELD(qts, (table)->signature, addr); \
ACPI_READ_FIELD((table)->length, addr); \ ACPI_READ_FIELD(qts, (table)->length, addr); \
ACPI_READ_FIELD((table)->revision, addr); \ ACPI_READ_FIELD(qts, (table)->revision, addr); \
ACPI_READ_FIELD((table)->checksum, addr); \ ACPI_READ_FIELD(qts, (table)->checksum, addr); \
ACPI_READ_ARRAY((table)->oem_id, addr); \ ACPI_READ_ARRAY(qts, (table)->oem_id, addr); \
ACPI_READ_ARRAY((table)->oem_table_id, addr); \ ACPI_READ_ARRAY(qts, (table)->oem_table_id, addr); \
ACPI_READ_FIELD((table)->oem_revision, addr); \ ACPI_READ_FIELD(qts, (table)->oem_revision, addr); \
ACPI_READ_ARRAY((table)->asl_compiler_id, addr); \ ACPI_READ_ARRAY(qts, (table)->asl_compiler_id, addr); \
ACPI_READ_FIELD((table)->asl_compiler_revision, addr); \ ACPI_READ_FIELD(qts, (table)->asl_compiler_revision, addr); \
} while (0) } while (0)
#define ACPI_ASSERT_CMP(actual, expected) do { \ #define ACPI_ASSERT_CMP(actual, expected) do { \
@ -70,18 +70,11 @@ typedef struct {
g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \ g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \
} while (0) } while (0)
#define ACPI_READ_GENERIC_ADDRESS(field, addr) \
do { \
ACPI_READ_FIELD((field).space_id, addr); \
ACPI_READ_FIELD((field).bit_width, addr); \
ACPI_READ_FIELD((field).bit_offset, addr); \
ACPI_READ_FIELD((field).access_width, addr); \
ACPI_READ_FIELD((field).address, addr); \
} while (0)
uint8_t acpi_calc_checksum(const uint8_t *data, int len); uint8_t acpi_calc_checksum(const uint8_t *data, int len);
uint32_t acpi_find_rsdp_address(void); uint32_t acpi_find_rsdp_address(QTestState *qts);
void acpi_parse_rsdp_table(uint32_t addr, AcpiRsdpDescriptor *rsdp_table); void acpi_parse_rsdp_table(QTestState *qts, uint32_t addr,
AcpiRsdpDescriptor *rsdp_table);
#endif /* TEST_ACPI_UTILS_H */ #endif /* TEST_ACPI_UTILS_H */

View File

@ -39,6 +39,7 @@ typedef struct {
struct smbios_21_entry_point smbios_ep_table; struct smbios_21_entry_point smbios_ep_table;
uint8_t *required_struct_types; uint8_t *required_struct_types;
int required_struct_types_len; int required_struct_types_len;
QTestState *qts;
} test_data; } test_data;
static char disk[] = "tests/acpi-test-disk-XXXXXX"; static char disk[] = "tests/acpi-test-disk-XXXXXX";
@ -78,7 +79,7 @@ static void free_test_data(test_data *data)
static void test_acpi_rsdp_address(test_data *data) static void test_acpi_rsdp_address(test_data *data)
{ {
uint32_t off = acpi_find_rsdp_address(); uint32_t off = acpi_find_rsdp_address(data->qts);
g_assert_cmphex(off, <, 0x100000); g_assert_cmphex(off, <, 0x100000);
data->rsdp_addr = off; data->rsdp_addr = off;
} }
@ -88,7 +89,7 @@ static void test_acpi_rsdp_table(test_data *data)
AcpiRsdpDescriptor *rsdp_table = &data->rsdp_table; AcpiRsdpDescriptor *rsdp_table = &data->rsdp_table;
uint32_t addr = data->rsdp_addr; uint32_t addr = data->rsdp_addr;
acpi_parse_rsdp_table(addr, rsdp_table); acpi_parse_rsdp_table(data->qts, addr, rsdp_table);
/* rsdp checksum is not for the whole table, but for the first 20 bytes */ /* rsdp checksum is not for the whole table, but for the first 20 bytes */
g_assert(!acpi_calc_checksum((uint8_t *)rsdp_table, 20)); g_assert(!acpi_calc_checksum((uint8_t *)rsdp_table, 20));
@ -104,7 +105,7 @@ static void test_acpi_rsdt_table(test_data *data)
uint32_t rsdt_table_length; uint32_t rsdt_table_length;
/* read the header */ /* read the header */
ACPI_READ_TABLE_HEADER(rsdt_table, addr); ACPI_READ_TABLE_HEADER(data->qts, rsdt_table, addr);
ACPI_ASSERT_CMP(rsdt_table->signature, "RSDT"); ACPI_ASSERT_CMP(rsdt_table->signature, "RSDT");
rsdt_table_length = le32_to_cpu(rsdt_table->length); rsdt_table_length = le32_to_cpu(rsdt_table->length);
@ -116,7 +117,7 @@ static void test_acpi_rsdt_table(test_data *data)
/* get the addresses of the tables pointed by rsdt */ /* get the addresses of the tables pointed by rsdt */
tables = g_new0(uint32_t, tables_nr); tables = g_new0(uint32_t, tables_nr);
ACPI_READ_ARRAY_PTR(tables, tables_nr, addr); ACPI_READ_ARRAY_PTR(data->qts, tables, tables_nr, addr);
checksum = acpi_calc_checksum((uint8_t *)rsdt_table, rsdt_table_length) + checksum = acpi_calc_checksum((uint8_t *)rsdt_table, rsdt_table_length) +
acpi_calc_checksum((uint8_t *)tables, acpi_calc_checksum((uint8_t *)tables,
@ -135,11 +136,11 @@ static void fadt_fetch_facs_and_dsdt_ptrs(test_data *data)
/* FADT table comes first */ /* FADT table comes first */
addr = le32_to_cpu(data->rsdt_tables_addr[0]); addr = le32_to_cpu(data->rsdt_tables_addr[0]);
ACPI_READ_TABLE_HEADER(&hdr, addr); ACPI_READ_TABLE_HEADER(data->qts, &hdr, addr);
ACPI_ASSERT_CMP(hdr.signature, "FACP"); ACPI_ASSERT_CMP(hdr.signature, "FACP");
ACPI_READ_FIELD(data->facs_addr, addr); ACPI_READ_FIELD(data->qts, data->facs_addr, addr);
ACPI_READ_FIELD(data->dsdt_addr, addr); ACPI_READ_FIELD(data->qts, data->dsdt_addr, addr);
} }
static void sanitize_fadt_ptrs(test_data *data) static void sanitize_fadt_ptrs(test_data *data)
@ -182,13 +183,13 @@ static void test_acpi_facs_table(test_data *data)
AcpiFacsDescriptorRev1 *facs_table = &data->facs_table; AcpiFacsDescriptorRev1 *facs_table = &data->facs_table;
uint32_t addr = le32_to_cpu(data->facs_addr); uint32_t addr = le32_to_cpu(data->facs_addr);
ACPI_READ_FIELD(facs_table->signature, addr); ACPI_READ_FIELD(data->qts, facs_table->signature, addr);
ACPI_READ_FIELD(facs_table->length, addr); ACPI_READ_FIELD(data->qts, facs_table->length, addr);
ACPI_READ_FIELD(facs_table->hardware_signature, addr); ACPI_READ_FIELD(data->qts, facs_table->hardware_signature, addr);
ACPI_READ_FIELD(facs_table->firmware_waking_vector, addr); ACPI_READ_FIELD(data->qts, facs_table->firmware_waking_vector, addr);
ACPI_READ_FIELD(facs_table->global_lock, addr); ACPI_READ_FIELD(data->qts, facs_table->global_lock, addr);
ACPI_READ_FIELD(facs_table->flags, addr); ACPI_READ_FIELD(data->qts, facs_table->flags, addr);
ACPI_READ_ARRAY(facs_table->resverved3, addr); ACPI_READ_ARRAY(data->qts, facs_table->resverved3, addr);
ACPI_ASSERT_CMP(facs_table->signature, "FACS"); ACPI_ASSERT_CMP(facs_table->signature, "FACS");
} }
@ -197,17 +198,17 @@ static void test_acpi_facs_table(test_data *data)
* load ACPI table at @addr into table descriptor @sdt_table * load ACPI table at @addr into table descriptor @sdt_table
* and check that header checksum matches actual one. * and check that header checksum matches actual one.
*/ */
static void fetch_table(AcpiSdtTable *sdt_table, uint32_t addr) static void fetch_table(QTestState *qts, AcpiSdtTable *sdt_table, uint32_t addr)
{ {
uint8_t checksum; uint8_t checksum;
memset(sdt_table, 0, sizeof(*sdt_table)); memset(sdt_table, 0, sizeof(*sdt_table));
ACPI_READ_TABLE_HEADER(&sdt_table->header, addr); ACPI_READ_TABLE_HEADER(qts, &sdt_table->header, addr);
sdt_table->aml_len = le32_to_cpu(sdt_table->header.length) sdt_table->aml_len = le32_to_cpu(sdt_table->header.length)
- sizeof(AcpiTableHeader); - sizeof(AcpiTableHeader);
sdt_table->aml = g_malloc0(sdt_table->aml_len); sdt_table->aml = g_malloc0(sdt_table->aml_len);
ACPI_READ_ARRAY_PTR(sdt_table->aml, sdt_table->aml_len, addr); ACPI_READ_ARRAY_PTR(qts, sdt_table->aml, sdt_table->aml_len, addr);
checksum = acpi_calc_checksum((uint8_t *)sdt_table, checksum = acpi_calc_checksum((uint8_t *)sdt_table,
sizeof(AcpiTableHeader)) + sizeof(AcpiTableHeader)) +
@ -221,7 +222,7 @@ static void test_acpi_dsdt_table(test_data *data)
AcpiSdtTable dsdt_table; AcpiSdtTable dsdt_table;
uint32_t addr = le32_to_cpu(data->dsdt_addr); uint32_t addr = le32_to_cpu(data->dsdt_addr);
fetch_table(&dsdt_table, addr); fetch_table(data->qts, &dsdt_table, addr);
ACPI_ASSERT_CMP(dsdt_table.header.signature, "DSDT"); ACPI_ASSERT_CMP(dsdt_table.header.signature, "DSDT");
/* Since DSDT isn't in RSDT, add DSDT to ASL test tables list manually */ /* Since DSDT isn't in RSDT, add DSDT to ASL test tables list manually */
@ -239,7 +240,7 @@ static void fetch_rsdt_referenced_tables(test_data *data)
uint32_t addr; uint32_t addr;
addr = le32_to_cpu(data->rsdt_tables_addr[i]); addr = le32_to_cpu(data->rsdt_tables_addr[i]);
fetch_table(&ssdt_table, addr); fetch_table(data->qts, &ssdt_table, addr);
/* Add table to ASL test tables list */ /* Add table to ASL test tables list */
g_array_append_val(data->tables, ssdt_table); g_array_append_val(data->tables, ssdt_table);
@ -371,6 +372,9 @@ static GArray *load_expected_aml(test_data *data)
gboolean ret; gboolean ret;
GArray *exp_tables = g_array_new(false, true, sizeof(AcpiSdtTable)); GArray *exp_tables = g_array_new(false, true, sizeof(AcpiSdtTable));
if (getenv("V")) {
fputc('\n', stderr);
}
for (i = 0; i < data->tables->len; ++i) { for (i = 0; i < data->tables->len; ++i) {
AcpiSdtTable exp_sdt; AcpiSdtTable exp_sdt;
gchar *aml_file = NULL; gchar *aml_file = NULL;
@ -385,7 +389,7 @@ try_again:
aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
(gchar *)&sdt->header.signature, ext); (gchar *)&sdt->header.signature, ext);
if (getenv("V")) { if (getenv("V")) {
fprintf(stderr, "\nLooking for expected file '%s'\n", aml_file); fprintf(stderr, "Looking for expected file '%s'\n", aml_file);
} }
if (g_file_test(aml_file, G_FILE_TEST_EXISTS)) { if (g_file_test(aml_file, G_FILE_TEST_EXISTS)) {
exp_sdt.aml_file = aml_file; exp_sdt.aml_file = aml_file;
@ -397,7 +401,7 @@ try_again:
} }
g_assert(exp_sdt.aml_file); g_assert(exp_sdt.aml_file);
if (getenv("V")) { if (getenv("V")) {
fprintf(stderr, "\nUsing expected file '%s'\n", aml_file); fprintf(stderr, "Using expected file '%s'\n", aml_file);
} }
ret = g_file_get_contents(aml_file, &exp_sdt.aml, ret = g_file_get_contents(aml_file, &exp_sdt.aml,
&exp_sdt.aml_len, &error); &exp_sdt.aml_len, &error);
@ -482,32 +486,32 @@ static bool smbios_ep_table_ok(test_data *data)
struct smbios_21_entry_point *ep_table = &data->smbios_ep_table; struct smbios_21_entry_point *ep_table = &data->smbios_ep_table;
uint32_t addr = data->smbios_ep_addr; uint32_t addr = data->smbios_ep_addr;
ACPI_READ_ARRAY(ep_table->anchor_string, addr); ACPI_READ_ARRAY(data->qts, ep_table->anchor_string, addr);
if (memcmp(ep_table->anchor_string, "_SM_", 4)) { if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
return false; return false;
} }
ACPI_READ_FIELD(ep_table->checksum, addr); ACPI_READ_FIELD(data->qts, ep_table->checksum, addr);
ACPI_READ_FIELD(ep_table->length, addr); ACPI_READ_FIELD(data->qts, ep_table->length, addr);
ACPI_READ_FIELD(ep_table->smbios_major_version, addr); ACPI_READ_FIELD(data->qts, ep_table->smbios_major_version, addr);
ACPI_READ_FIELD(ep_table->smbios_minor_version, addr); ACPI_READ_FIELD(data->qts, ep_table->smbios_minor_version, addr);
ACPI_READ_FIELD(ep_table->max_structure_size, addr); ACPI_READ_FIELD(data->qts, ep_table->max_structure_size, addr);
ACPI_READ_FIELD(ep_table->entry_point_revision, addr); ACPI_READ_FIELD(data->qts, ep_table->entry_point_revision, addr);
ACPI_READ_ARRAY(ep_table->formatted_area, addr); ACPI_READ_ARRAY(data->qts, ep_table->formatted_area, addr);
ACPI_READ_ARRAY(ep_table->intermediate_anchor_string, addr); ACPI_READ_ARRAY(data->qts, ep_table->intermediate_anchor_string, addr);
if (memcmp(ep_table->intermediate_anchor_string, "_DMI_", 5)) { if (memcmp(ep_table->intermediate_anchor_string, "_DMI_", 5)) {
return false; return false;
} }
ACPI_READ_FIELD(ep_table->intermediate_checksum, addr); ACPI_READ_FIELD(data->qts, ep_table->intermediate_checksum, addr);
ACPI_READ_FIELD(ep_table->structure_table_length, addr); ACPI_READ_FIELD(data->qts, ep_table->structure_table_length, addr);
if (ep_table->structure_table_length == 0) { if (ep_table->structure_table_length == 0) {
return false; return false;
} }
ACPI_READ_FIELD(ep_table->structure_table_address, addr); ACPI_READ_FIELD(data->qts, ep_table->structure_table_address, addr);
ACPI_READ_FIELD(ep_table->number_of_structures, addr); ACPI_READ_FIELD(data->qts, ep_table->number_of_structures, addr);
if (ep_table->number_of_structures == 0) { if (ep_table->number_of_structures == 0) {
return false; return false;
} }
ACPI_READ_FIELD(ep_table->smbios_bcd_revision, addr); ACPI_READ_FIELD(data->qts, ep_table->smbios_bcd_revision, addr);
if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table) || if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table) ||
acpi_calc_checksum((uint8_t *)ep_table + 0x10, acpi_calc_checksum((uint8_t *)ep_table + 0x10,
sizeof *ep_table - 0x10)) { sizeof *ep_table - 0x10)) {
@ -526,7 +530,7 @@ static void test_smbios_entry_point(test_data *data)
int i; int i;
for (i = 0; i < sizeof sig - 1; ++i) { for (i = 0; i < sizeof sig - 1; ++i) {
sig[i] = readb(off + i); sig[i] = qtest_readb(data->qts, off + i);
} }
if (!memcmp(sig, "_SM_", sizeof sig)) { if (!memcmp(sig, "_SM_", sizeof sig)) {
@ -569,9 +573,9 @@ static void test_smbios_structs(test_data *data)
for (i = 0; i < le16_to_cpu(ep_table->number_of_structures); i++) { for (i = 0; i < le16_to_cpu(ep_table->number_of_structures); i++) {
/* grab type and formatted area length from struct header */ /* grab type and formatted area length from struct header */
type = readb(addr); type = qtest_readb(data->qts, addr);
g_assert_cmpuint(type, <=, SMBIOS_MAX_TYPE); g_assert_cmpuint(type, <=, SMBIOS_MAX_TYPE);
len = readb(addr + 1); len = qtest_readb(data->qts, addr + 1);
/* single-instance structs must not have been encountered before */ /* single-instance structs must not have been encountered before */
if (smbios_single_instance(type)) { if (smbios_single_instance(type)) {
@ -583,7 +587,7 @@ static void test_smbios_structs(test_data *data)
prv = crt = 1; prv = crt = 1;
while (prv || crt) { while (prv || crt) {
prv = crt; prv = crt;
crt = readb(addr + len); crt = qtest_readb(data->qts, addr + len);
len++; len++;
} }
@ -620,9 +624,9 @@ static void test_acpi_one(const char *params, test_data *data)
data->machine, "kvm:tcg", data->machine, "kvm:tcg",
params ? params : "", disk); params ? params : "", disk);
qtest_start(args); data->qts = qtest_init(args);
boot_sector_test(global_qtest); boot_sector_test(data->qts);
data->tables = g_array_new(false, true, sizeof(AcpiSdtTable)); data->tables = g_array_new(false, true, sizeof(AcpiSdtTable));
test_acpi_rsdp_address(data); test_acpi_rsdp_address(data);
@ -646,7 +650,8 @@ static void test_acpi_one(const char *params, test_data *data)
test_smbios_entry_point(data); test_smbios_entry_point(data);
test_smbios_structs(data); test_smbios_structs(data);
qtest_quit(global_qtest); assert(!global_qtest);
qtest_quit(data->qts);
g_free(args); g_free(args);
} }

View File

@ -128,13 +128,14 @@ static testdef_t tests[] = {
{ NULL } { NULL }
}; };
static bool check_guest_output(const testdef_t *test, int fd) static bool check_guest_output(QTestState *qts, const testdef_t *test, int fd)
{ {
int i, nbr = 0, pos = 0, ccnt; int nbr = 0, pos = 0, ccnt;
time_t now, start = time(NULL);
char ch; char ch;
/* Poll serial output... Wait at most 360 seconds */ /* Poll serial output... */
for (i = 0; i < 36000; ++i) { while (1) {
ccnt = 0; ccnt = 0;
while (ccnt++ < 512 && (nbr = read(fd, &ch, 1)) == 1) { while (ccnt++ < 512 && (nbr = read(fd, &ch, 1)) == 1) {
if (ch == test->expect[pos]) { if (ch == test->expect[pos]) {
@ -148,6 +149,15 @@ static bool check_guest_output(const testdef_t *test, int fd)
} }
} }
g_assert(nbr >= 0); g_assert(nbr >= 0);
/* Wait only if the child is still alive. */
if (!qtest_probe_child(qts)) {
break;
}
/* Wait at most 360 seconds. */
now = time(NULL);
if (now - start >= 360) {
break;
}
g_usleep(10000); g_usleep(10000);
} }
@ -161,6 +171,7 @@ static void test_machine(const void *data)
char codetmp[] = "/tmp/qtest-boot-serial-cXXXXXX"; char codetmp[] = "/tmp/qtest-boot-serial-cXXXXXX";
const char *codeparam = ""; const char *codeparam = "";
const uint8_t *code = NULL; const uint8_t *code = NULL;
QTestState *qts;
int ser_fd; int ser_fd;
ser_fd = mkstemp(serialtmp); ser_fd = mkstemp(serialtmp);
@ -189,22 +200,22 @@ static void test_machine(const void *data)
* Make sure that this test uses tcg if available: It is used as a * Make sure that this test uses tcg if available: It is used as a
* fast-enough smoketest for that. * fast-enough smoketest for that.
*/ */
global_qtest = qtest_initf("%s %s -M %s,accel=tcg:kvm " qts = qtest_initf("%s %s -M %s,accel=tcg:kvm -no-shutdown "
"-chardev file,id=serial0,path=%s " "-chardev file,id=serial0,path=%s "
"-no-shutdown -serial chardev:serial0 %s", "-serial chardev:serial0 %s",
codeparam, code ? codetmp : "", codeparam, code ? codetmp : "", test->machine,
test->machine, serialtmp, test->extra); serialtmp, test->extra);
if (code) { if (code) {
unlink(codetmp); unlink(codetmp);
} }
if (!check_guest_output(test, ser_fd)) { if (!check_guest_output(qts, test, ser_fd)) {
g_error("Failed to find expected string. Please check '%s'", g_error("Failed to find expected string. Please check '%s'",
serialtmp); serialtmp);
} }
unlink(serialtmp); unlink(serialtmp);
qtest_quit(global_qtest); qtest_quit(qts);
close(ser_fd); close(ser_fd);
} }

View File

@ -71,13 +71,10 @@ static const char* reg2str(enum Reg reg) {
static inline unsigned in_reg(IVState *s, enum Reg reg) static inline unsigned in_reg(IVState *s, enum Reg reg)
{ {
const char *name = reg2str(reg); const char *name = reg2str(reg);
QTestState *qtest = global_qtest;
unsigned res; unsigned res;
global_qtest = s->qs->qts;
res = qpci_io_readl(s->dev, s->reg_bar, reg); res = qpci_io_readl(s->dev, s->reg_bar, reg);
g_test_message("*%s -> %x\n", name, res); g_test_message("*%s -> %x\n", name, res);
global_qtest = qtest;
return res; return res;
} }
@ -85,35 +82,25 @@ static inline unsigned in_reg(IVState *s, enum Reg reg)
static inline void out_reg(IVState *s, enum Reg reg, unsigned v) static inline void out_reg(IVState *s, enum Reg reg, unsigned v)
{ {
const char *name = reg2str(reg); const char *name = reg2str(reg);
QTestState *qtest = global_qtest;
global_qtest = s->qs->qts;
g_test_message("%x -> *%s\n", v, name); g_test_message("%x -> *%s\n", v, name);
qpci_io_writel(s->dev, s->reg_bar, reg, v); qpci_io_writel(s->dev, s->reg_bar, reg, v);
global_qtest = qtest;
} }
static inline void read_mem(IVState *s, uint64_t off, void *buf, size_t len) static inline void read_mem(IVState *s, uint64_t off, void *buf, size_t len)
{ {
QTestState *qtest = global_qtest;
global_qtest = s->qs->qts;
qpci_memread(s->dev, s->mem_bar, off, buf, len); qpci_memread(s->dev, s->mem_bar, off, buf, len);
global_qtest = qtest;
} }
static inline void write_mem(IVState *s, uint64_t off, static inline void write_mem(IVState *s, uint64_t off,
const void *buf, size_t len) const void *buf, size_t len)
{ {
QTestState *qtest = global_qtest;
global_qtest = s->qs->qts;
qpci_memwrite(s->dev, s->mem_bar, off, buf, len); qpci_memwrite(s->dev, s->mem_bar, off, buf, len);
global_qtest = qtest;
} }
static void cleanup_vm(IVState *s) static void cleanup_vm(IVState *s)
{ {
assert(!global_qtest);
g_free(s->dev); g_free(s->dev);
qtest_shutdown(s->qs); qtest_shutdown(s->qs);
} }
@ -131,7 +118,6 @@ static void setup_vm_cmd(IVState *s, const char *cmd, bool msix)
g_printerr("ivshmem-test tests are only available on x86 or ppc64\n"); g_printerr("ivshmem-test tests are only available on x86 or ppc64\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
global_qtest = s->qs->qts;
s->dev = get_device(s->qs->pcibus); s->dev = get_device(s->qs->pcibus);
s->reg_bar = qpci_iomap(s->dev, 0, &barsize); s->reg_bar = qpci_iomap(s->dev, 0, &barsize);
@ -354,7 +340,6 @@ static void test_ivshmem_server(bool msi)
g_assert_cmpint(vm1, !=, vm2); g_assert_cmpint(vm1, !=, vm2);
/* check number of MSI-X vectors */ /* check number of MSI-X vectors */
global_qtest = s1->qs->qts;
if (msi) { if (msi) {
ret = qpci_msix_table_size(s1->dev); ret = qpci_msix_table_size(s1->dev);
g_assert_cmpuint(ret, ==, nvectors); g_assert_cmpuint(ret, ==, nvectors);
@ -377,7 +362,6 @@ static void test_ivshmem_server(bool msi)
g_assert_cmpuint(ret, !=, 0); g_assert_cmpuint(ret, !=, 0);
/* ping vm1 -> vm2 on vector 1 */ /* ping vm1 -> vm2 on vector 1 */
global_qtest = s2->qs->qts;
if (msi) { if (msi) {
ret = qpci_msix_pending(s2->dev, 1); ret = qpci_msix_pending(s2->dev, 1);
g_assert_cmpuint(ret, ==, 0); g_assert_cmpuint(ret, ==, 0);

View File

@ -29,90 +29,91 @@ typedef struct QPCIBusPC
static uint8_t qpci_pc_pio_readb(QPCIBus *bus, uint32_t addr) static uint8_t qpci_pc_pio_readb(QPCIBus *bus, uint32_t addr)
{ {
return inb(addr); return qtest_inb(bus->qts, addr);
} }
static void qpci_pc_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val) static void qpci_pc_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
{ {
outb(addr, val); qtest_outb(bus->qts, addr, val);
} }
static uint16_t qpci_pc_pio_readw(QPCIBus *bus, uint32_t addr) static uint16_t qpci_pc_pio_readw(QPCIBus *bus, uint32_t addr)
{ {
return inw(addr); return qtest_inw(bus->qts, addr);
} }
static void qpci_pc_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val) static void qpci_pc_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
{ {
outw(addr, val); qtest_outw(bus->qts, addr, val);
} }
static uint32_t qpci_pc_pio_readl(QPCIBus *bus, uint32_t addr) static uint32_t qpci_pc_pio_readl(QPCIBus *bus, uint32_t addr)
{ {
return inl(addr); return qtest_inl(bus->qts, addr);
} }
static void qpci_pc_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val) static void qpci_pc_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
{ {
outl(addr, val); qtest_outl(bus->qts, addr, val);
} }
static uint64_t qpci_pc_pio_readq(QPCIBus *bus, uint32_t addr) static uint64_t qpci_pc_pio_readq(QPCIBus *bus, uint32_t addr)
{ {
return (uint64_t)inl(addr) + ((uint64_t)inl(addr + 4) << 32); return (uint64_t)qtest_inl(bus->qts, addr) +
((uint64_t)qtest_inl(bus->qts, addr + 4) << 32);
} }
static void qpci_pc_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val) static void qpci_pc_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
{ {
outl(addr, val & 0xffffffff); qtest_outl(bus->qts, addr, val & 0xffffffff);
outl(addr + 4, val >> 32); qtest_outl(bus->qts, addr + 4, val >> 32);
} }
static void qpci_pc_memread(QPCIBus *bus, uint32_t addr, void *buf, size_t len) static void qpci_pc_memread(QPCIBus *bus, uint32_t addr, void *buf, size_t len)
{ {
memread(addr, buf, len); qtest_memread(bus->qts, addr, buf, len);
} }
static void qpci_pc_memwrite(QPCIBus *bus, uint32_t addr, static void qpci_pc_memwrite(QPCIBus *bus, uint32_t addr,
const void *buf, size_t len) const void *buf, size_t len)
{ {
memwrite(addr, buf, len); qtest_memwrite(bus->qts, addr, buf, len);
} }
static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset) static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
{ {
outl(0xcf8, (1U << 31) | (devfn << 8) | offset); qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
return inb(0xcfc); return qtest_inb(bus->qts, 0xcfc);
} }
static uint16_t qpci_pc_config_readw(QPCIBus *bus, int devfn, uint8_t offset) static uint16_t qpci_pc_config_readw(QPCIBus *bus, int devfn, uint8_t offset)
{ {
outl(0xcf8, (1U << 31) | (devfn << 8) | offset); qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
return inw(0xcfc); return qtest_inw(bus->qts, 0xcfc);
} }
static uint32_t qpci_pc_config_readl(QPCIBus *bus, int devfn, uint8_t offset) static uint32_t qpci_pc_config_readl(QPCIBus *bus, int devfn, uint8_t offset)
{ {
outl(0xcf8, (1U << 31) | (devfn << 8) | offset); qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
return inl(0xcfc); return qtest_inl(bus->qts, 0xcfc);
} }
static void qpci_pc_config_writeb(QPCIBus *bus, int devfn, uint8_t offset, uint8_t value) static void qpci_pc_config_writeb(QPCIBus *bus, int devfn, uint8_t offset, uint8_t value)
{ {
outl(0xcf8, (1U << 31) | (devfn << 8) | offset); qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
outb(0xcfc, value); qtest_outb(bus->qts, 0xcfc, value);
} }
static void qpci_pc_config_writew(QPCIBus *bus, int devfn, uint8_t offset, uint16_t value) static void qpci_pc_config_writew(QPCIBus *bus, int devfn, uint8_t offset, uint16_t value)
{ {
outl(0xcf8, (1U << 31) | (devfn << 8) | offset); qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
outw(0xcfc, value); qtest_outw(bus->qts, 0xcfc, value);
} }
static void qpci_pc_config_writel(QPCIBus *bus, int devfn, uint8_t offset, uint32_t value) static void qpci_pc_config_writel(QPCIBus *bus, int devfn, uint8_t offset, uint32_t value)
{ {
outl(0xcf8, (1U << 31) | (devfn << 8) | offset); qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
outl(0xcfc, value); qtest_outl(bus->qts, 0xcfc, value);
} }
QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc) QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc)

View File

@ -45,63 +45,63 @@ typedef struct QPCIBusSPAPR {
static uint8_t qpci_spapr_pio_readb(QPCIBus *bus, uint32_t addr) static uint8_t qpci_spapr_pio_readb(QPCIBus *bus, uint32_t addr)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
return readb(s->pio_cpu_base + addr); return qtest_readb(bus->qts, s->pio_cpu_base + addr);
} }
static void qpci_spapr_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val) static void qpci_spapr_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
writeb(s->pio_cpu_base + addr, val); qtest_writeb(bus->qts, s->pio_cpu_base + addr, val);
} }
static uint16_t qpci_spapr_pio_readw(QPCIBus *bus, uint32_t addr) static uint16_t qpci_spapr_pio_readw(QPCIBus *bus, uint32_t addr)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
return bswap16(readw(s->pio_cpu_base + addr)); return bswap16(qtest_readw(bus->qts, s->pio_cpu_base + addr));
} }
static void qpci_spapr_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val) static void qpci_spapr_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
writew(s->pio_cpu_base + addr, bswap16(val)); qtest_writew(bus->qts, s->pio_cpu_base + addr, bswap16(val));
} }
static uint32_t qpci_spapr_pio_readl(QPCIBus *bus, uint32_t addr) static uint32_t qpci_spapr_pio_readl(QPCIBus *bus, uint32_t addr)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
return bswap32(readl(s->pio_cpu_base + addr)); return bswap32(qtest_readl(bus->qts, s->pio_cpu_base + addr));
} }
static void qpci_spapr_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val) static void qpci_spapr_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
writel(s->pio_cpu_base + addr, bswap32(val)); qtest_writel(bus->qts, s->pio_cpu_base + addr, bswap32(val));
} }
static uint64_t qpci_spapr_pio_readq(QPCIBus *bus, uint32_t addr) static uint64_t qpci_spapr_pio_readq(QPCIBus *bus, uint32_t addr)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
return bswap64(readq(s->pio_cpu_base + addr)); return bswap64(qtest_readq(bus->qts, s->pio_cpu_base + addr));
} }
static void qpci_spapr_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val) static void qpci_spapr_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
writeq(s->pio_cpu_base + addr, bswap64(val)); qtest_writeq(bus->qts, s->pio_cpu_base + addr, bswap64(val));
} }
static void qpci_spapr_memread(QPCIBus *bus, uint32_t addr, static void qpci_spapr_memread(QPCIBus *bus, uint32_t addr,
void *buf, size_t len) void *buf, size_t len)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
memread(s->mmio32_cpu_base + addr, buf, len); qtest_memread(bus->qts, s->mmio32_cpu_base + addr, buf, len);
} }
static void qpci_spapr_memwrite(QPCIBus *bus, uint32_t addr, static void qpci_spapr_memwrite(QPCIBus *bus, uint32_t addr,
const void *buf, size_t len) const void *buf, size_t len)
{ {
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus); QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
memwrite(s->mmio32_cpu_base + addr, buf, len); qtest_memwrite(bus->qts, s->mmio32_cpu_base + addr, buf, len);
} }
static uint8_t qpci_spapr_config_readb(QPCIBus *bus, int devfn, uint8_t offset) static uint8_t qpci_spapr_config_readb(QPCIBus *bus, int devfn, uint8_t offset)

View File

@ -39,10 +39,11 @@ struct QTestState
{ {
int fd; int fd;
int qmp_fd; int qmp_fd;
pid_t qemu_pid; /* our child QEMU process */
int wstatus;
bool big_endian;
bool irq_level[MAX_IRQ]; bool irq_level[MAX_IRQ];
GString *rx; GString *rx;
pid_t qemu_pid; /* our child QEMU process */
bool big_endian;
}; };
static GHookList abrt_hooks; static GHookList abrt_hooks;
@ -96,36 +97,52 @@ static int socket_accept(int sock)
return ret; return ret;
} }
bool qtest_probe_child(QTestState *s)
{
pid_t pid = s->qemu_pid;
if (pid != -1) {
pid = waitpid(pid, &s->wstatus, WNOHANG);
if (pid == 0) {
return true;
}
s->qemu_pid = -1;
}
return false;
}
static void kill_qemu(QTestState *s) static void kill_qemu(QTestState *s)
{ {
if (s->qemu_pid != -1) { pid_t pid = s->qemu_pid;
int wstatus = 0; int wstatus;
pid_t pid;
kill(s->qemu_pid, SIGTERM);
TFR(pid = waitpid(s->qemu_pid, &wstatus, 0));
/* Skip wait if qtest_probe_child already reaped. */
if (pid != -1) {
kill(pid, SIGTERM);
TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0));
assert(pid == s->qemu_pid); assert(pid == s->qemu_pid);
/* }
* We expect qemu to exit with status 0; anything else is
* fishy and should be logged with as much detail as possible.
*/
if (wstatus) {
if (WIFEXITED(wstatus)) {
fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU "
"process but encountered exit status %d\n",
__FILE__, __LINE__, WEXITSTATUS(wstatus));
} else if (WIFSIGNALED(wstatus)) {
int sig = WTERMSIG(wstatus);
const char *signame = strsignal(sig) ?: "unknown ???";
const char *dump = WCOREDUMP(wstatus) ? " (core dumped)" : "";
fprintf(stderr, "%s:%d: kill_qemu() detected QEMU death " /*
"from signal %d (%s)%s\n", * We expect qemu to exit with status 0; anything else is
__FILE__, __LINE__, sig, signame, dump); * fishy and should be logged with as much detail as possible.
} */
abort(); wstatus = s->wstatus;
if (wstatus) {
if (WIFEXITED(wstatus)) {
fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU "
"process but encountered exit status %d\n",
__FILE__, __LINE__, WEXITSTATUS(wstatus));
} else if (WIFSIGNALED(wstatus)) {
int sig = WTERMSIG(wstatus);
const char *signame = strsignal(sig) ?: "unknown ???";
const char *dump = WCOREDUMP(wstatus) ? " (core dumped)" : "";
fprintf(stderr, "%s:%d: kill_qemu() detected QEMU death "
"from signal %d (%s)%s\n",
__FILE__, __LINE__, sig, signame, dump);
} }
abort();
} }
} }
@ -228,6 +245,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
g_test_message("starting QEMU: %s", command); g_test_message("starting QEMU: %s", command);
s->wstatus = 0;
s->qemu_pid = fork(); s->qemu_pid = fork();
if (s->qemu_pid == 0) { if (s->qemu_pid == 0) {
setenv("QEMU_AUDIO_DRV", "none", true); setenv("QEMU_AUDIO_DRV", "none", true);

View File

@ -1011,4 +1011,12 @@ bool qmp_rsp_is_err(QDict *rsp);
*/ */
void qmp_assert_error_class(QDict *rsp, const char *class); void qmp_assert_error_class(QDict *rsp, const char *class);
/**
* qtest_probe_child:
* @s: QTestState instance to operate on.
*
* Returns: true if the child is still alive.
*/
bool qtest_probe_child(QTestState *s);
#endif #endif

View File

@ -75,6 +75,7 @@ static void test_machine_cpu_cli(void)
QDict *response; QDict *response;
const char *arch = qtest_get_arch(); const char *arch = qtest_get_arch();
const char *cpu_model = get_cpu_model_by_arch(arch); const char *cpu_model = get_cpu_model_by_arch(arch);
QTestState *qts;
if (!cpu_model) { if (!cpu_model) {
if (!(!strcmp(arch, "microblaze") || !strcmp(arch, "microblazeel"))) { if (!(!strcmp(arch, "microblaze") || !strcmp(arch, "microblazeel"))) {
@ -83,13 +84,13 @@ static void test_machine_cpu_cli(void)
} }
return; /* TODO: die here to force all targets have a test */ return; /* TODO: die here to force all targets have a test */
} }
global_qtest = qtest_initf("-machine none -cpu '%s'", cpu_model); qts = qtest_initf("-machine none -cpu '%s'", cpu_model);
response = qmp("{ 'execute': 'quit' }"); response = qtest_qmp(qts, "{ 'execute': 'quit' }");
g_assert(qdict_haskey(response, "return")); g_assert(qdict_haskey(response, "return"));
qobject_unref(response); qobject_unref(response);
qtest_quit(global_qtest); qtest_quit(qts);
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View File

@ -25,14 +25,14 @@
#define MAGIC 0xcafec0de #define MAGIC 0xcafec0de
#define ADDRESS 0x4000 #define ADDRESS 0x4000
static void check_guest_memory(void) static void check_guest_memory(QTestState *qts)
{ {
uint32_t signature; uint32_t signature;
int i; int i;
/* Poll until code has run and modified memory. Wait at most 600 seconds */ /* Poll until code has run and modified memory. Wait at most 600 seconds */
for (i = 0; i < 60000; ++i) { for (i = 0; i < 60000; ++i) {
signature = readl(ADDRESS); signature = qtest_readl(qts, ADDRESS);
if (signature == MAGIC) { if (signature == MAGIC) {
break; break;
} }
@ -45,17 +45,16 @@ static void check_guest_memory(void)
static void test_machine(const void *machine) static void test_machine(const void *machine)
{ {
const char *extra_args; const char *extra_args;
QTestState *qts;
/* The pseries firmware boots much faster without the default devices */ /* The pseries firmware boots much faster without the default devices */
extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : ""; extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : "";
global_qtest = qtest_initf("-M %s,accel=tcg %s " qts = qtest_initf("-M %s,accel=tcg %s -prom-env 'use-nvramrc?=true' "
"-prom-env 'use-nvramrc?=true' " "-prom-env 'nvramrc=%x %x l!' ", (const char *)machine,
"-prom-env 'nvramrc=%x %x l!' ", extra_args, MAGIC, ADDRESS);
(const char *)machine, extra_args, check_guest_memory(qts);
MAGIC, ADDRESS); qtest_quit(qts);
check_guest_memory();
qtest_quit(global_qtest);
} }
static void add_tests(const char *machines[]) static void add_tests(const char *machines[])

View File

@ -15,13 +15,16 @@ static void test_panic(void)
{ {
uint8_t val; uint8_t val;
QDict *response, *data; QDict *response, *data;
QTestState *qts;
val = inb(0x505); qts = qtest_init("-device pvpanic");
val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, 1); g_assert_cmpuint(val, ==, 1);
outb(0x505, 0x1); qtest_outb(qts, 0x505, 0x1);
response = qmp_receive(); response = qtest_qmp_receive(qts);
g_assert(qdict_haskey(response, "event")); g_assert(qdict_haskey(response, "event"));
g_assert_cmpstr(qdict_get_str(response, "event"), ==, "GUEST_PANICKED"); g_assert_cmpstr(qdict_get_str(response, "event"), ==, "GUEST_PANICKED");
g_assert(qdict_haskey(response, "data")); g_assert(qdict_haskey(response, "data"));
@ -29,6 +32,8 @@ static void test_panic(void)
g_assert(qdict_haskey(data, "action")); g_assert(qdict_haskey(data, "action"));
g_assert_cmpstr(qdict_get_str(data, "action"), ==, "pause"); g_assert_cmpstr(qdict_get_str(data, "action"), ==, "pause");
qobject_unref(response); qobject_unref(response);
qtest_quit(qts);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -38,10 +43,7 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL); g_test_init(&argc, &argv, NULL);
qtest_add_func("/pvpanic/panic", test_panic); qtest_add_func("/pvpanic/panic", test_panic);
qtest_start("-device pvpanic");
ret = g_test_run(); ret = g_test_run();
qtest_end();
return ret; return ret;
} }

View File

@ -61,6 +61,7 @@ static testdef_t s390x_tests[] = {
static void test_pxe_one(const testdef_t *test, bool ipv6) static void test_pxe_one(const testdef_t *test, bool ipv6)
{ {
QTestState *qts;
char *args; char *args;
args = g_strdup_printf( args = g_strdup_printf(
@ -70,9 +71,9 @@ static void test_pxe_one(const testdef_t *test, bool ipv6)
test->machine, disk, ipv6 ? "off" : "on", ipv6 ? "on" : "off", test->machine, disk, ipv6 ? "off" : "on", ipv6 ? "on" : "off",
test->model); test->model);
qtest_start(args); qts = qtest_init(args);
boot_sector_test(global_qtest); boot_sector_test(qts);
qtest_quit(global_qtest); qtest_quit(qts);
g_free(args); g_free(args);
} }

View File

@ -17,7 +17,7 @@
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
/* TODO actually test the results and get rid of this */ /* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__)) #define qmp_discard_response(qs, ...) qobject_unref(qtest_qmp(qs, __VA_ARGS__))
static void test_mirror(void) static void test_mirror(void)
{ {
@ -29,6 +29,7 @@ static void test_mirror(void)
uint32_t size = sizeof(send_buf); uint32_t size = sizeof(send_buf);
size = htonl(size); size = htonl(size);
const char *devstr = "e1000"; const char *devstr = "e1000";
QTestState *qts;
if (g_str_equal(qtest_get_arch(), "s390x")) { if (g_str_equal(qtest_get_arch(), "s390x")) {
devstr = "virtio-net-ccw"; devstr = "virtio-net-ccw";
@ -40,7 +41,7 @@ static void test_mirror(void)
ret = mkstemp(sock_path); ret = mkstemp(sock_path);
g_assert_cmpint(ret, !=, -1); g_assert_cmpint(ret, !=, -1);
global_qtest = qtest_initf( qts = qtest_initf(
"-netdev socket,id=qtest-bn0,fd=%d " "-netdev socket,id=qtest-bn0,fd=%d "
"-device %s,netdev=qtest-bn0,id=qtest-e0 " "-device %s,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=mirror0,path=%s,server,nowait " "-chardev socket,id=mirror0,path=%s,server,nowait "
@ -61,7 +62,7 @@ static void test_mirror(void)
}; };
/* send a qmp command to guarantee that 'connected' is setting to true. */ /* send a qmp command to guarantee that 'connected' is setting to true. */
qmp_discard_response("{ 'execute' : 'query-status'}"); qmp_discard_response(qts, "{ 'execute' : 'query-status'}");
ret = iov_send(send_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf)); ret = iov_send(send_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf));
g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size)); g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));
close(send_sock[0]); close(send_sock[0]);
@ -78,6 +79,7 @@ static void test_mirror(void)
g_free(recv_buf); g_free(recv_buf);
close(recv_sock); close(recv_sock);
unlink(sock_path); unlink(sock_path);
qtest_quit(qts);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -88,7 +90,6 @@ int main(int argc, char **argv)
qtest_add_func("/netfilter/mirror", test_mirror); qtest_add_func("/netfilter/mirror", test_mirror);
ret = g_test_run(); ret = g_test_run();
qtest_end();
return ret; return ret;
} }

View File

@ -59,7 +59,7 @@
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
/* TODO actually test the results and get rid of this */ /* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__)) #define qmp_discard_response(qs, ...) qobject_unref(qtest_qmp(qs, __VA_ARGS__))
static const char *get_devstr(void) static const char *get_devstr(void)
{ {
@ -81,6 +81,7 @@ static void test_redirector_tx(void)
char *recv_buf; char *recv_buf;
uint32_t size = sizeof(send_buf); uint32_t size = sizeof(send_buf);
size = htonl(size); size = htonl(size);
QTestState *qts;
ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock); ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock);
g_assert_cmpint(ret, !=, -1); g_assert_cmpint(ret, !=, -1);
@ -90,7 +91,7 @@ static void test_redirector_tx(void)
ret = mkstemp(sock_path1); ret = mkstemp(sock_path1);
g_assert_cmpint(ret, !=, -1); g_assert_cmpint(ret, !=, -1);
global_qtest = qtest_initf( qts = qtest_initf(
"-netdev socket,id=qtest-bn0,fd=%d " "-netdev socket,id=qtest-bn0,fd=%d "
"-device %s,netdev=qtest-bn0,id=qtest-e0 " "-device %s,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait " "-chardev socket,id=redirector0,path=%s,server,nowait "
@ -108,7 +109,7 @@ static void test_redirector_tx(void)
g_assert_cmpint(recv_sock, !=, -1); g_assert_cmpint(recv_sock, !=, -1);
/* send a qmp command to guarantee that 'connected' is setting to true. */ /* send a qmp command to guarantee that 'connected' is setting to true. */
qmp_discard_response("{ 'execute' : 'query-status'}"); qmp_discard_response(qts, "{ 'execute' : 'query-status'}");
struct iovec iov[] = { struct iovec iov[] = {
{ {
@ -137,7 +138,7 @@ static void test_redirector_tx(void)
close(recv_sock); close(recv_sock);
unlink(sock_path0); unlink(sock_path0);
unlink(sock_path1); unlink(sock_path1);
qtest_end(); qtest_quit(qts);
} }
static void test_redirector_rx(void) static void test_redirector_rx(void)
@ -150,6 +151,7 @@ static void test_redirector_rx(void)
char *recv_buf; char *recv_buf;
uint32_t size = sizeof(send_buf); uint32_t size = sizeof(send_buf);
size = htonl(size); size = htonl(size);
QTestState *qts;
ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock); ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock);
g_assert_cmpint(ret, !=, -1); g_assert_cmpint(ret, !=, -1);
@ -159,7 +161,7 @@ static void test_redirector_rx(void)
ret = mkstemp(sock_path1); ret = mkstemp(sock_path1);
g_assert_cmpint(ret, !=, -1); g_assert_cmpint(ret, !=, -1);
global_qtest = qtest_initf( qts = qtest_initf(
"-netdev socket,id=qtest-bn0,fd=%d " "-netdev socket,id=qtest-bn0,fd=%d "
"-device %s,netdev=qtest-bn0,id=qtest-e0 " "-device %s,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait " "-chardev socket,id=redirector0,path=%s,server,nowait "
@ -186,7 +188,7 @@ static void test_redirector_rx(void)
send_sock = unix_connect(sock_path1, NULL); send_sock = unix_connect(sock_path1, NULL);
g_assert_cmpint(send_sock, !=, -1); g_assert_cmpint(send_sock, !=, -1);
/* send a qmp command to guarantee that 'connected' is setting to true. */ /* send a qmp command to guarantee that 'connected' is setting to true. */
qmp_discard_response("{ 'execute' : 'query-status'}"); qmp_discard_response(qts, "{ 'execute' : 'query-status'}");
ret = iov_send(send_sock, iov, 2, 0, sizeof(size) + sizeof(send_buf)); ret = iov_send(send_sock, iov, 2, 0, sizeof(size) + sizeof(send_buf));
g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size)); g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));
@ -204,7 +206,7 @@ static void test_redirector_rx(void)
g_free(recv_buf); g_free(recv_buf);
unlink(sock_path0); unlink(sock_path0);
unlink(sock_path1); unlink(sock_path1);
qtest_end(); qtest_quit(qts);
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View File

@ -31,7 +31,7 @@ typedef struct {
uint32_t vgia_val; uint32_t vgia_val;
} QEMU_PACKED VgidTable; } QEMU_PACKED VgidTable;
static uint32_t acpi_find_vgia(void) static uint32_t acpi_find_vgia(QTestState *qts)
{ {
uint32_t rsdp_offset; uint32_t rsdp_offset;
uint32_t guid_offset = 0; uint32_t guid_offset = 0;
@ -45,18 +45,18 @@ static uint32_t acpi_find_vgia(void)
int i; int i;
/* Wait for guest firmware to finish and start the payload. */ /* Wait for guest firmware to finish and start the payload. */
boot_sector_test(global_qtest); boot_sector_test(qts);
/* Tables should be initialized now. */ /* Tables should be initialized now. */
rsdp_offset = acpi_find_rsdp_address(); rsdp_offset = acpi_find_rsdp_address(qts);
g_assert_cmphex(rsdp_offset, <, RSDP_ADDR_INVALID); g_assert_cmphex(rsdp_offset, <, RSDP_ADDR_INVALID);
acpi_parse_rsdp_table(rsdp_offset, &rsdp_table); acpi_parse_rsdp_table(qts, rsdp_offset, &rsdp_table);
rsdt = le32_to_cpu(rsdp_table.rsdt_physical_address); rsdt = le32_to_cpu(rsdp_table.rsdt_physical_address);
/* read the header */ /* read the header */
ACPI_READ_TABLE_HEADER(&rsdt_table, rsdt); ACPI_READ_TABLE_HEADER(qts, &rsdt_table, rsdt);
ACPI_ASSERT_CMP(rsdt_table.signature, "RSDT"); ACPI_ASSERT_CMP(rsdt_table.signature, "RSDT");
rsdt_table_length = le32_to_cpu(rsdt_table.length); rsdt_table_length = le32_to_cpu(rsdt_table.length);
@ -67,22 +67,22 @@ static uint32_t acpi_find_vgia(void)
/* get the addresses of the tables pointed by rsdt */ /* get the addresses of the tables pointed by rsdt */
tables = g_new0(uint32_t, tables_nr); tables = g_new0(uint32_t, tables_nr);
ACPI_READ_ARRAY_PTR(tables, tables_nr, rsdt); ACPI_READ_ARRAY_PTR(qts, tables, tables_nr, rsdt);
for (i = 0; i < tables_nr; i++) { for (i = 0; i < tables_nr; i++) {
uint32_t addr = le32_to_cpu(tables[i]); uint32_t addr = le32_to_cpu(tables[i]);
ACPI_READ_TABLE_HEADER(&ssdt_table, addr); ACPI_READ_TABLE_HEADER(qts, &ssdt_table, addr);
if (!strncmp((char *)ssdt_table.oem_table_id, "VMGENID", 7)) { if (!strncmp((char *)ssdt_table.oem_table_id, "VMGENID", 7)) {
/* the first entry in the table should be VGIA /* the first entry in the table should be VGIA
* That's all we need * That's all we need
*/ */
ACPI_READ_FIELD(vgid_table.name_op, addr); ACPI_READ_FIELD(qts, vgid_table.name_op, addr);
g_assert(vgid_table.name_op == 0x08); /* name */ g_assert(vgid_table.name_op == 0x08); /* name */
ACPI_READ_ARRAY(vgid_table.vgia, addr); ACPI_READ_ARRAY(qts, vgid_table.vgia, addr);
g_assert(memcmp(vgid_table.vgia, "VGIA", 4) == 0); g_assert(memcmp(vgid_table.vgia, "VGIA", 4) == 0);
ACPI_READ_FIELD(vgid_table.val_op, addr); ACPI_READ_FIELD(qts, vgid_table.val_op, addr);
g_assert(vgid_table.val_op == 0x0C); /* dword */ g_assert(vgid_table.val_op == 0x0C); /* dword */
ACPI_READ_FIELD(vgid_table.vgia_val, addr); ACPI_READ_FIELD(qts, vgid_table.vgia_val, addr);
/* The GUID is written at a fixed offset into the fw_cfg file /* The GUID is written at a fixed offset into the fw_cfg file
* in order to implement the "OVMF SDT Header probe suppressor" * in order to implement the "OVMF SDT Header probe suppressor"
* see docs/specs/vmgenid.txt for more details * see docs/specs/vmgenid.txt for more details
@ -95,17 +95,17 @@ static uint32_t acpi_find_vgia(void)
return guid_offset; return guid_offset;
} }
static void read_guid_from_memory(QemuUUID *guid) static void read_guid_from_memory(QTestState *qts, QemuUUID *guid)
{ {
uint32_t vmgenid_addr; uint32_t vmgenid_addr;
int i; int i;
vmgenid_addr = acpi_find_vgia(); vmgenid_addr = acpi_find_vgia(qts);
g_assert(vmgenid_addr); g_assert(vmgenid_addr);
/* Read the GUID directly from guest memory */ /* Read the GUID directly from guest memory */
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
guid->data[i] = readb(vmgenid_addr + i); guid->data[i] = qtest_readb(qts, vmgenid_addr + i);
} }
/* The GUID is in little-endian format in the guest, while QEMU /* The GUID is in little-endian format in the guest, while QEMU
* uses big-endian. Swap after reading. * uses big-endian. Swap after reading.
@ -113,12 +113,12 @@ static void read_guid_from_memory(QemuUUID *guid)
qemu_uuid_bswap(guid); qemu_uuid_bswap(guid);
} }
static void read_guid_from_monitor(QemuUUID *guid) static void read_guid_from_monitor(QTestState *qts, QemuUUID *guid)
{ {
QDict *rsp, *rsp_ret; QDict *rsp, *rsp_ret;
const char *guid_str; const char *guid_str;
rsp = qmp("{ 'execute': 'query-vm-generation-id' }"); rsp = qtest_qmp(qts, "{ 'execute': 'query-vm-generation-id' }");
if (qdict_haskey(rsp, "return")) { if (qdict_haskey(rsp, "return")) {
rsp_ret = qdict_get_qdict(rsp, "return"); rsp_ret = qdict_get_qdict(rsp, "return");
g_assert(qdict_haskey(rsp_ret, "guid")); g_assert(qdict_haskey(rsp_ret, "guid"));
@ -139,45 +139,48 @@ static char disk[] = "tests/vmgenid-test-disk-XXXXXX";
static void vmgenid_set_guid_test(void) static void vmgenid_set_guid_test(void)
{ {
QemuUUID expected, measured; QemuUUID expected, measured;
QTestState *qts;
g_assert(qemu_uuid_parse(VGID_GUID, &expected) == 0); g_assert(qemu_uuid_parse(VGID_GUID, &expected) == 0);
global_qtest = qtest_initf(GUID_CMD(VGID_GUID)); qts = qtest_initf(GUID_CMD(VGID_GUID));
/* Read the GUID from accessing guest memory */ /* Read the GUID from accessing guest memory */
read_guid_from_memory(&measured); read_guid_from_memory(qts, &measured);
g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) == 0); g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) == 0);
qtest_quit(global_qtest); qtest_quit(qts);
} }
static void vmgenid_set_guid_auto_test(void) static void vmgenid_set_guid_auto_test(void)
{ {
QemuUUID measured; QemuUUID measured;
QTestState *qts;
global_qtest = qtest_initf(GUID_CMD("auto")); qts = qtest_initf(GUID_CMD("auto"));
read_guid_from_memory(&measured); read_guid_from_memory(qts, &measured);
/* Just check that the GUID is non-null */ /* Just check that the GUID is non-null */
g_assert(!qemu_uuid_is_null(&measured)); g_assert(!qemu_uuid_is_null(&measured));
qtest_quit(global_qtest); qtest_quit(qts);
} }
static void vmgenid_query_monitor_test(void) static void vmgenid_query_monitor_test(void)
{ {
QemuUUID expected, measured; QemuUUID expected, measured;
QTestState *qts;
g_assert(qemu_uuid_parse(VGID_GUID, &expected) == 0); g_assert(qemu_uuid_parse(VGID_GUID, &expected) == 0);
global_qtest = qtest_initf(GUID_CMD(VGID_GUID)); qts = qtest_initf(GUID_CMD(VGID_GUID));
/* Read the GUID via the monitor */ /* Read the GUID via the monitor */
read_guid_from_monitor(&measured); read_guid_from_monitor(qts, &measured);
g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) == 0); g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) == 0);
qtest_quit(global_qtest); qtest_quit(qts);
} }
int main(int argc, char **argv) int main(int argc, char **argv)