diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/bench/meson.build | 6 | ||||
-rw-r--r-- | tests/bench/xbzrle-bench.c | 469 | ||||
-rw-r--r-- | tests/migration/guestperf/engine.py | 2 | ||||
-rwxr-xr-x | tests/qemu-iotests/186 | 1 | ||||
-rw-r--r-- | tests/qtest/bios-tables-test.c | 75 | ||||
-rw-r--r-- | tests/qtest/device-plug-test.c | 41 | ||||
-rw-r--r-- | tests/qtest/drive_del-test.c | 65 | ||||
-rw-r--r-- | tests/qtest/fuzz-lsi53c895a-test.c | 4 | ||||
-rw-r--r-- | tests/qtest/hd-geo-test.c | 38 | ||||
-rw-r--r-- | tests/qtest/meson.build | 17 | ||||
-rw-r--r-- | tests/qtest/npcm7xx_pwm-test.c | 27 | ||||
-rw-r--r-- | tests/qtest/pxe-test.c | 4 | ||||
-rw-r--r-- | tests/tcg/s390x/Makefile.softmmu-target | 2 | ||||
-rw-r--r-- | tests/unit/test-xbzrle.c | 39 |
14 files changed, 746 insertions, 44 deletions
diff --git a/tests/bench/meson.build b/tests/bench/meson.build index 279a8fcc33..7477a1f401 100644 --- a/tests/bench/meson.build +++ b/tests/bench/meson.build @@ -3,6 +3,12 @@ qht_bench = executable('qht-bench', sources: 'qht-bench.c', dependencies: [qemuutil]) +if have_system +xbzrle_bench = executable('xbzrle-bench', + sources: 'xbzrle-bench.c', + dependencies: [qemuutil,migration]) +endif + executable('atomic_add-bench', sources: files('atomic_add-bench.c'), dependencies: [qemuutil], diff --git a/tests/bench/xbzrle-bench.c b/tests/bench/xbzrle-bench.c new file mode 100644 index 0000000000..8848a3a32d --- /dev/null +++ b/tests/bench/xbzrle-bench.c @@ -0,0 +1,469 @@ +/* + * Xor Based Zero Run Length Encoding unit tests. + * + * Copyright 2013 Red Hat, Inc. and/or its affiliates + * + * Authors: + * Orit Wasserman <owasserm@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#include "qemu/osdep.h" +#include "qemu/cutils.h" +#include "../migration/xbzrle.h" + +#if defined(CONFIG_AVX512BW_OPT) +#define XBZRLE_PAGE_SIZE 4096 +static bool is_cpu_support_avx512bw; +#include "qemu/cpuid.h" +static void __attribute__((constructor)) init_cpu_flag(void) +{ + unsigned max = __get_cpuid_max(0, NULL); + int a, b, c, d; + is_cpu_support_avx512bw = false; + if (max >= 1) { + __cpuid(1, a, b, c, d); + /* We must check that AVX is not just available, but usable. */ + if ((c & bit_OSXSAVE) && (c & bit_AVX) && max >= 7) { + int bv; + __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0)); + __cpuid_count(7, 0, a, b, c, d); + /* 0xe6: + * XCR0[7:5] = 111b (OPMASK state, upper 256-bit of ZMM0-ZMM15 + * and ZMM16-ZMM31 state are enabled by OS) + * XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS) + */ + if ((bv & 0xe6) == 0xe6 && (b & bit_AVX512BW)) { + is_cpu_support_avx512bw = true; + } + } + } + return ; +} + +struct ResTime { + float t_raw; + float t_512; +}; + + +/* Function prototypes +int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen, + uint8_t *dst, int dlen); +*/ +static void encode_decode_zero(struct ResTime *res) +{ + uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE); + int i = 0; + int dlen = 0, dlen512 = 0; + int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); + + for (i = diff_len; i > 0; i--) { + buffer[1000 + i] = i; + buffer512[1000 + i] = i; + } + + buffer[1000 + diff_len + 3] = 103; + buffer[1000 + diff_len + 5] = 105; + + buffer512[1000 + diff_len + 3] = 103; + buffer512[1000 + diff_len + 5] = 105; + + /* encode zero page */ + time_t t_start, t_end, t_start512, t_end512; + t_start = clock(); + dlen = xbzrle_encode_buffer(buffer, buffer, XBZRLE_PAGE_SIZE, compressed, + XBZRLE_PAGE_SIZE); + t_end = clock(); + float time_val = difftime(t_end, t_start); + g_assert(dlen == 0); + + t_start512 = clock(); + dlen512 = xbzrle_encode_buffer_avx512(buffer512, buffer512, XBZRLE_PAGE_SIZE, + compressed512, XBZRLE_PAGE_SIZE); + t_end512 = clock(); + float time_val512 = difftime(t_end512, t_start512); + g_assert(dlen512 == 0); + + res->t_raw = time_val; + res->t_512 = time_val512; + + g_free(buffer); + g_free(compressed); + g_free(buffer512); + g_free(compressed512); + +} + +static void test_encode_decode_zero_avx512(void) +{ + int i; + float time_raw = 0.0, time_512 = 0.0; + struct ResTime res; + for (i = 0; i < 10000; i++) { + encode_decode_zero(&res); + time_raw += res.t_raw; + time_512 += res.t_512; + } + printf("Zero test:\n"); + printf("Raw xbzrle_encode time is %f ms\n", time_raw); + printf("512 xbzrle_encode time is %f ms\n", time_512); +} + +static void encode_decode_unchanged(struct ResTime *res) +{ + uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); + int i = 0; + int dlen = 0, dlen512 = 0; + int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); + + for (i = diff_len; i > 0; i--) { + test[1000 + i] = i + 4; + test512[1000 + i] = i + 4; + } + + test[1000 + diff_len + 3] = 107; + test[1000 + diff_len + 5] = 109; + + test512[1000 + diff_len + 3] = 107; + test512[1000 + diff_len + 5] = 109; + + /* test unchanged buffer */ + time_t t_start, t_end, t_start512, t_end512; + t_start = clock(); + dlen = xbzrle_encode_buffer(test, test, XBZRLE_PAGE_SIZE, compressed, + XBZRLE_PAGE_SIZE); + t_end = clock(); + float time_val = difftime(t_end, t_start); + g_assert(dlen == 0); + + t_start512 = clock(); + dlen512 = xbzrle_encode_buffer_avx512(test512, test512, XBZRLE_PAGE_SIZE, + compressed512, XBZRLE_PAGE_SIZE); + t_end512 = clock(); + float time_val512 = difftime(t_end512, t_start512); + g_assert(dlen512 == 0); + + res->t_raw = time_val; + res->t_512 = time_val512; + + g_free(test); + g_free(compressed); + g_free(test512); + g_free(compressed512); + +} + +static void test_encode_decode_unchanged_avx512(void) +{ + int i; + float time_raw = 0.0, time_512 = 0.0; + struct ResTime res; + for (i = 0; i < 10000; i++) { + encode_decode_unchanged(&res); + time_raw += res.t_raw; + time_512 += res.t_512; + } + printf("Unchanged test:\n"); + printf("Raw xbzrle_encode time is %f ms\n", time_raw); + printf("512 xbzrle_encode time is %f ms\n", time_512); +} + +static void encode_decode_1_byte(struct ResTime *res) +{ + uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE); + uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE); + int dlen = 0, rc = 0, dlen512 = 0, rc512 = 0; + uint8_t buf[2]; + uint8_t buf512[2]; + + test[XBZRLE_PAGE_SIZE - 1] = 1; + test512[XBZRLE_PAGE_SIZE - 1] = 1; + + time_t t_start, t_end, t_start512, t_end512; + t_start = clock(); + dlen = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed, + XBZRLE_PAGE_SIZE); + t_end = clock(); + float time_val = difftime(t_end, t_start); + g_assert(dlen == (uleb128_encode_small(&buf[0], 4095) + 2)); + + rc = xbzrle_decode_buffer(compressed, dlen, buffer, XBZRLE_PAGE_SIZE); + g_assert(rc == XBZRLE_PAGE_SIZE); + g_assert(memcmp(test, buffer, XBZRLE_PAGE_SIZE) == 0); + + t_start512 = clock(); + dlen512 = xbzrle_encode_buffer_avx512(buffer512, test512, XBZRLE_PAGE_SIZE, + compressed512, XBZRLE_PAGE_SIZE); + t_end512 = clock(); + float time_val512 = difftime(t_end512, t_start512); + g_assert(dlen512 == (uleb128_encode_small(&buf512[0], 4095) + 2)); + + rc512 = xbzrle_decode_buffer(compressed512, dlen512, buffer512, + XBZRLE_PAGE_SIZE); + g_assert(rc512 == XBZRLE_PAGE_SIZE); + g_assert(memcmp(test512, buffer512, XBZRLE_PAGE_SIZE) == 0); + + res->t_raw = time_val; + res->t_512 = time_val512; + + g_free(buffer); + g_free(compressed); + g_free(test); + g_free(buffer512); + g_free(compressed512); + g_free(test512); + +} + +static void test_encode_decode_1_byte_avx512(void) +{ + int i; + float time_raw = 0.0, time_512 = 0.0; + struct ResTime res; + for (i = 0; i < 10000; i++) { + encode_decode_1_byte(&res); + time_raw += res.t_raw; + time_512 += res.t_512; + } + printf("1 byte test:\n"); + printf("Raw xbzrle_encode time is %f ms\n", time_raw); + printf("512 xbzrle_encode time is %f ms\n", time_512); +} + +static void encode_decode_overflow(struct ResTime *res) +{ + uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); + int i = 0, rc = 0, rc512 = 0; + + for (i = 0; i < XBZRLE_PAGE_SIZE / 2 - 1; i++) { + test[i * 2] = 1; + test512[i * 2] = 1; + } + + /* encode overflow */ + time_t t_start, t_end, t_start512, t_end512; + t_start = clock(); + rc = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed, + XBZRLE_PAGE_SIZE); + t_end = clock(); + float time_val = difftime(t_end, t_start); + g_assert(rc == -1); + + t_start512 = clock(); + rc512 = xbzrle_encode_buffer_avx512(buffer512, test512, XBZRLE_PAGE_SIZE, + compressed512, XBZRLE_PAGE_SIZE); + t_end512 = clock(); + float time_val512 = difftime(t_end512, t_start512); + g_assert(rc512 == -1); + + res->t_raw = time_val; + res->t_512 = time_val512; + + g_free(buffer); + g_free(compressed); + g_free(test); + g_free(buffer512); + g_free(compressed512); + g_free(test512); + +} + +static void test_encode_decode_overflow_avx512(void) +{ + int i; + float time_raw = 0.0, time_512 = 0.0; + struct ResTime res; + for (i = 0; i < 10000; i++) { + encode_decode_overflow(&res); + time_raw += res.t_raw; + time_512 += res.t_512; + } + printf("Overflow test:\n"); + printf("Raw xbzrle_encode time is %f ms\n", time_raw); + printf("512 xbzrle_encode time is %f ms\n", time_512); +} + +static void encode_decode_range_avx512(struct ResTime *res) +{ + uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE); + uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE); + uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); + int i = 0, rc = 0, rc512 = 0; + int dlen = 0, dlen512 = 0; + + int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); + + for (i = diff_len; i > 0; i--) { + buffer[1000 + i] = i; + test[1000 + i] = i + 4; + buffer512[1000 + i] = i; + test512[1000 + i] = i + 4; + } + + buffer[1000 + diff_len + 3] = 103; + test[1000 + diff_len + 3] = 107; + + buffer[1000 + diff_len + 5] = 105; + test[1000 + diff_len + 5] = 109; + + buffer512[1000 + diff_len + 3] = 103; + test512[1000 + diff_len + 3] = 107; + + buffer512[1000 + diff_len + 5] = 105; + test512[1000 + diff_len + 5] = 109; + + /* test encode/decode */ + time_t t_start, t_end, t_start512, t_end512; + t_start = clock(); + dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, compressed, + XBZRLE_PAGE_SIZE); + t_end = clock(); + float time_val = difftime(t_end, t_start); + rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE); + g_assert(rc < XBZRLE_PAGE_SIZE); + g_assert(memcmp(test, buffer, XBZRLE_PAGE_SIZE) == 0); + + t_start512 = clock(); + dlen512 = xbzrle_encode_buffer_avx512(test512, buffer512, XBZRLE_PAGE_SIZE, + compressed512, XBZRLE_PAGE_SIZE); + t_end512 = clock(); + float time_val512 = difftime(t_end512, t_start512); + rc512 = xbzrle_decode_buffer(compressed512, dlen512, test512, XBZRLE_PAGE_SIZE); + g_assert(rc512 < XBZRLE_PAGE_SIZE); + g_assert(memcmp(test512, buffer512, XBZRLE_PAGE_SIZE) == 0); + + res->t_raw = time_val; + res->t_512 = time_val512; + + g_free(buffer); + g_free(compressed); + g_free(test); + g_free(buffer512); + g_free(compressed512); + g_free(test512); + +} + +static void test_encode_decode_avx512(void) +{ + int i; + float time_raw = 0.0, time_512 = 0.0; + struct ResTime res; + for (i = 0; i < 10000; i++) { + encode_decode_range_avx512(&res); + time_raw += res.t_raw; + time_512 += res.t_512; + } + printf("Encode decode test:\n"); + printf("Raw xbzrle_encode time is %f ms\n", time_raw); + printf("512 xbzrle_encode time is %f ms\n", time_512); +} + +static void encode_decode_random(struct ResTime *res) +{ + uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE); + uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); + uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE); + uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); + int i = 0, rc = 0, rc512 = 0; + int dlen = 0, dlen512 = 0; + + int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1); + /* store the index of diff */ + int dirty_index[diff_len]; + for (int j = 0; j < diff_len; j++) { + dirty_index[j] = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1); + } + for (i = diff_len - 1; i >= 0; i--) { + buffer[dirty_index[i]] = i; + test[dirty_index[i]] = i + 4; + buffer512[dirty_index[i]] = i; + test512[dirty_index[i]] = i + 4; + } + + time_t t_start, t_end, t_start512, t_end512; + t_start = clock(); + dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, compressed, + XBZRLE_PAGE_SIZE); + t_end = clock(); + float time_val = difftime(t_end, t_start); + rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE); + g_assert(rc < XBZRLE_PAGE_SIZE); + + t_start512 = clock(); + dlen512 = xbzrle_encode_buffer_avx512(test512, buffer512, XBZRLE_PAGE_SIZE, + compressed512, XBZRLE_PAGE_SIZE); + t_end512 = clock(); + float time_val512 = difftime(t_end512, t_start512); + rc512 = xbzrle_decode_buffer(compressed512, dlen512, test512, XBZRLE_PAGE_SIZE); + g_assert(rc512 < XBZRLE_PAGE_SIZE); + + res->t_raw = time_val; + res->t_512 = time_val512; + + g_free(buffer); + g_free(compressed); + g_free(test); + g_free(buffer512); + g_free(compressed512); + g_free(test512); + +} + +static void test_encode_decode_random_avx512(void) +{ + int i; + float time_raw = 0.0, time_512 = 0.0; + struct ResTime res; + for (i = 0; i < 10000; i++) { + encode_decode_random(&res); + time_raw += res.t_raw; + time_512 += res.t_512; + } + printf("Random test:\n"); + printf("Raw xbzrle_encode time is %f ms\n", time_raw); + printf("512 xbzrle_encode time is %f ms\n", time_512); +} +#endif + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + g_test_rand_int(); + #if defined(CONFIG_AVX512BW_OPT) + if (likely(is_cpu_support_avx512bw)) { + g_test_add_func("/xbzrle/encode_decode_zero", test_encode_decode_zero_avx512); + g_test_add_func("/xbzrle/encode_decode_unchanged", + test_encode_decode_unchanged_avx512); + g_test_add_func("/xbzrle/encode_decode_1_byte", test_encode_decode_1_byte_avx512); + g_test_add_func("/xbzrle/encode_decode_overflow", + test_encode_decode_overflow_avx512); + g_test_add_func("/xbzrle/encode_decode", test_encode_decode_avx512); + g_test_add_func("/xbzrle/encode_decode_random", test_encode_decode_random_avx512); + } + #endif + return g_test_run(); +} diff --git a/tests/migration/guestperf/engine.py b/tests/migration/guestperf/engine.py index cc06fac592..e69d16a62c 100644 --- a/tests/migration/guestperf/engine.py +++ b/tests/migration/guestperf/engine.py @@ -337,7 +337,7 @@ class Engine(object): argv.extend(self._get_qemu_serial_args()) if self._debug: - argv.extend(["-device", "sga"]) + argv.extend(["-machine", "graphics=off"]) if hardware._prealloc_pages: argv_source += ["-mem-path", "/dev/shm", diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186 index 072e54e62b..eaf13c7a33 100755 --- a/tests/qemu-iotests/186 +++ b/tests/qemu-iotests/186 @@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file fuse _require_drivers null-co +_require_devices virtio-scsi-pci if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then _notrun "Requires a PC machine" diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index d8c8cda58e..d29a4e47af 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -1008,6 +1008,12 @@ static void test_acpi_q35_multif_bridge(void) .machine = MACHINE_Q35, .variant = ".multi-bridge", }; + + if (!qtest_has_device("pcie-root-port")) { + g_test_skip("Device pcie-root-port is not available"); + goto out; + } + test_vm_prepare("-S" " -device virtio-balloon,id=balloon0,addr=0x4.0x2" " -device pcie-root-port,id=rp0,multifunction=on," @@ -1043,6 +1049,7 @@ static void test_acpi_q35_multif_bridge(void) /* check that reboot/reset doesn't change any ACPI tables */ qtest_qmp_send(data.qts, "{'execute':'system_reset' }"); process_acpi_tables(&data); +out: free_test_data(&data); } @@ -1396,6 +1403,11 @@ static void test_acpi_tcg_dimm_pxm(const char *machine) { test_data data; + if (!qtest_has_device("nvdimm")) { + g_test_skip("Device nvdimm is not available"); + return; + } + memset(&data, 0, sizeof(data)); data.machine = machine; data.variant = ".dimmpxm"; @@ -1444,6 +1456,11 @@ static void test_acpi_virt_tcg_memhp(void) .scan_len = 256ULL * 1024 * 1024, }; + if (!qtest_has_device("nvdimm")) { + g_test_skip("Device nvdimm is not available"); + goto out; + } + data.variant = ".memhp"; test_acpi_one(" -machine nvdimm=on" " -cpu cortex-a57" @@ -1457,7 +1474,7 @@ static void test_acpi_virt_tcg_memhp(void) " -device pc-dimm,id=dimm0,memdev=ram2,node=0" " -device nvdimm,id=dimm1,memdev=nvm0,node=1", &data); - +out: free_test_data(&data); } @@ -1475,6 +1492,11 @@ static void test_acpi_microvm_tcg(void) { test_data data; + if (!qtest_has_device("virtio-blk-device")) { + g_test_skip("Device virtio-blk-device is not available"); + return; + } + test_acpi_microvm_prepare(&data); test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=off", &data); @@ -1485,6 +1507,11 @@ static void test_acpi_microvm_usb_tcg(void) { test_data data; + if (!qtest_has_device("virtio-blk-device")) { + g_test_skip("Device virtio-blk-device is not available"); + return; + } + test_acpi_microvm_prepare(&data); data.variant = ".usb"; test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,usb=on,rtc=off", @@ -1496,6 +1523,11 @@ static void test_acpi_microvm_rtc_tcg(void) { test_data data; + if (!qtest_has_device("virtio-blk-device")) { + g_test_skip("Device virtio-blk-device is not available"); + return; + } + test_acpi_microvm_prepare(&data); data.variant = ".rtc"; test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=on", @@ -1507,6 +1539,11 @@ static void test_acpi_microvm_pcie_tcg(void) { test_data data; + if (!qtest_has_device("virtio-blk-device")) { + g_test_skip("Device virtio-blk-device is not available"); + return; + } + test_acpi_microvm_prepare(&data); data.variant = ".pcie"; data.tcg_only = true; /* need constant host-phys-bits */ @@ -1519,6 +1556,11 @@ static void test_acpi_microvm_ioapic2_tcg(void) { test_data data; + if (!qtest_has_device("virtio-blk-device")) { + g_test_skip("Device virtio-blk-device is not available"); + return; + } + test_acpi_microvm_prepare(&data); data.variant = ".ioapic2"; test_acpi_one(" -machine microvm,acpi=on,ioapic2=on,rtc=off", @@ -1558,6 +1600,12 @@ static void test_acpi_virt_tcg_pxb(void) .ram_start = 0x40000000ULL, .scan_len = 128ULL * 1024 * 1024, }; + + if (!qtest_has_device("pcie-root-port")) { + g_test_skip("Device pcie-root-port is not available"); + goto out; + } + /* * While using -cdrom, the cdrom would auto plugged into pxb-pcie, * the reason is the bus of pxb-pcie is also root bus, it would lead @@ -1576,7 +1624,7 @@ static void test_acpi_virt_tcg_pxb(void) " -cpu cortex-a57" " -device pxb-pcie,bus_nr=128", &data); - +out: free_test_data(&data); } @@ -1764,6 +1812,12 @@ static void test_acpi_microvm_acpi_erst(void) gchar *params; test_data data; + if (!qtest_has_device("virtio-blk-device")) { + g_test_skip("Device virtio-blk-device is not available"); + g_free(tmp_path); + return; + } + test_acpi_microvm_prepare(&data); data.variant = ".pcie"; data.tcg_only = true; /* need constant host-phys-bits */ @@ -1824,6 +1878,11 @@ static void test_acpi_q35_viot(void) .variant = ".viot", }; + if (!qtest_has_device("virtio-iommu")) { + g_test_skip("Device virtio-iommu is not available"); + goto out; + } + /* * To keep things interesting, two buses bypass the IOMMU. * VIOT should only describes the other two buses. @@ -1834,6 +1893,7 @@ static void test_acpi_q35_viot(void) "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on " "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0", &data); +out: free_test_data(&data); } @@ -1894,8 +1954,10 @@ static void test_acpi_virt_viot(void) .scan_len = 128ULL * 1024 * 1024, }; - test_acpi_one("-cpu cortex-a57 " - "-device virtio-iommu-pci", &data); + if (qtest_has_device("virtio-iommu")) { + test_acpi_one("-cpu cortex-a57 " + "-device virtio-iommu-pci", &data); + } free_test_data(&data); } @@ -2004,6 +2066,11 @@ static void test_acpi_microvm_oem_fields(void) test_data data; char *args; + if (!qtest_has_device("virtio-blk-device")) { + g_test_skip("Device virtio-blk-device is not available"); + return; + } + test_acpi_microvm_prepare(&data); args = test_acpi_create_args(&data, diff --git a/tests/qtest/device-plug-test.c b/tests/qtest/device-plug-test.c index 5a6afa2b57..01cecd6e20 100644 --- a/tests/qtest/device-plug-test.c +++ b/tests/qtest/device-plug-test.c @@ -64,15 +64,21 @@ static void process_device_remove(QTestState *qtest, const char *id) static void test_pci_unplug_request(void) { + QTestState *qtest; const char *arch = qtest_get_arch(); const char *machine_addition = ""; + if (!qtest_has_device("virtio-mouse-pci")) { + g_test_skip("Device virtio-mouse-pci not available"); + return; + } + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { machine_addition = "-machine pc"; } - QTestState *qtest = qtest_initf("%s -device virtio-mouse-pci,id=dev0", - machine_addition); + qtest = qtest_initf("%s -device virtio-mouse-pci,id=dev0", + machine_addition); process_device_remove(qtest, "dev0"); @@ -81,11 +87,17 @@ static void test_pci_unplug_request(void) static void test_q35_pci_unplug_request(void) { + QTestState *qtest; + + if (!qtest_has_device("virtio-mouse-pci")) { + g_test_skip("Device virtio-mouse-pci not available"); + return; + } - QTestState *qtest = qtest_initf("-machine q35 " - "-device pcie-root-port,id=p1 " - "-device pcie-pci-bridge,bus=p1,id=b1 " - "-device virtio-mouse-pci,bus=b1,id=dev0"); + qtest = qtest_initf("-machine q35 " + "-device pcie-root-port,id=p1 " + "-device pcie-pci-bridge,bus=p1,id=b1 " + "-device virtio-mouse-pci,bus=b1,id=dev0"); process_device_remove(qtest, "dev0"); @@ -94,14 +106,20 @@ static void test_q35_pci_unplug_request(void) static void test_pci_unplug_json_request(void) { + QTestState *qtest; const char *arch = qtest_get_arch(); const char *machine_addition = ""; + if (!qtest_has_device("virtio-mouse-pci")) { + g_test_skip("Device virtio-mouse-pci not available"); + return; + } + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { machine_addition = "-machine pc"; } - QTestState *qtest = qtest_initf( + qtest = qtest_initf( "%s -device \"{'driver': 'virtio-mouse-pci', 'id': 'dev0'}\"", machine_addition); @@ -112,6 +130,7 @@ static void test_pci_unplug_json_request(void) static void test_q35_pci_unplug_json_request(void) { + QTestState *qtest; const char *port = "-device \"{'driver': 'pcie-root-port', " "'id': 'p1'}\""; @@ -123,8 +142,12 @@ static void test_q35_pci_unplug_json_request(void) "'bus': 'b1', " "'id': 'dev0'}\""; - QTestState *qtest = qtest_initf("-machine q35 %s %s %s", - port, bridge, device); + if (!qtest_has_device("virtio-mouse-pci")) { + g_test_skip("Device virtio-mouse-pci not available"); + return; + } + + qtest = qtest_initf("-machine q35 %s %s %s", port, bridge, device); process_device_remove(qtest, "dev0"); diff --git a/tests/qtest/drive_del-test.c b/tests/qtest/drive_del-test.c index 9a750395a9..8a6f3ac963 100644 --- a/tests/qtest/drive_del-test.c +++ b/tests/qtest/drive_del-test.c @@ -16,6 +16,8 @@ #include "qapi/qmp/qdict.h" #include "qapi/qmp/qlist.h" +static const char *qvirtio_get_dev_type(void); + static bool look_for_drive0(QTestState *qts, const char *command, const char *key) { QDict *response; @@ -40,6 +42,19 @@ static bool look_for_drive0(QTestState *qts, const char *command, const char *ke return found; } +/* + * This covers the possible absence of a device due to QEMU build + * options. + */ +static bool has_device_builtin(const char *dev) +{ + gchar *device = g_strdup_printf("%s-%s", dev, qvirtio_get_dev_type()); + bool rc = qtest_has_device(device); + + g_free(device); + return rc; +} + static bool has_drive(QTestState *qts) { return look_for_drive0(qts, "query-block", "device"); @@ -208,6 +223,11 @@ static void test_drive_del_device_del(void) { QTestState *qts; + if (!has_device_builtin("virtio-scsi")) { + g_test_skip("Device virtio-scsi is not available"); + return; + } + /* Start with a drive used by a device that unplugs instantaneously */ qts = qtest_initf("-drive if=none,id=drive0,file=null-co://," "file.read-zeroes=on,format=raw" @@ -232,6 +252,11 @@ static void test_cli_device_del(void) const char *arch = qtest_get_arch(); const char *machine_addition = ""; + if (!has_device_builtin("virtio-blk")) { + g_test_skip("Device virtio-blk is not available"); + return; + } + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { machine_addition = "-machine pc"; } @@ -256,6 +281,11 @@ static void test_cli_device_del_q35(void) { QTestState *qts; + if (!has_device_builtin("virtio-blk")) { + g_test_skip("Device virtio-blk is not available"); + return; + } + /* * -drive/-device and device_del. Start with a drive used by a * device that unplugs after reset. @@ -277,6 +307,11 @@ static void test_empty_device_del(void) { QTestState *qts; + if (!has_device_builtin("virtio-scsi")) { + g_test_skip("Device virtio-scsi is not available"); + return; + } + /* device_del with no drive plugged. */ qts = qtest_initf("-device virtio-scsi-%s -device scsi-cd,id=dev0", qvirtio_get_dev_type()); @@ -291,6 +326,11 @@ static void test_device_add_and_del(void) const char *arch = qtest_get_arch(); const char *machine_addition = ""; + if (!has_device_builtin("virtio-blk")) { + g_test_skip("Device virtio-blk is not available"); + return; + } + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { machine_addition = "-machine pc"; } @@ -330,6 +370,11 @@ static void test_device_add_and_del_q35(void) { QTestState *qts; + if (!has_device_builtin("virtio-blk")) { + g_test_skip("Device virtio-blk is not available"); + return; + } + /* * -drive/device_add and device_del. Start with a drive used by a * device that unplugs after reset. @@ -352,6 +397,11 @@ static void test_drive_add_device_add_and_del(void) const char *arch = qtest_get_arch(); const char *machine_addition = ""; + if (!has_device_builtin("virtio-blk")) { + g_test_skip("Device virtio-blk is not available"); + return; + } + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { machine_addition = "-machine pc"; } @@ -374,6 +424,11 @@ static void test_drive_add_device_add_and_del_q35(void) { QTestState *qts; + if (!has_device_builtin("virtio-blk")) { + g_test_skip("Device virtio-blk is not available"); + return; + } + qts = qtest_init("-machine q35 -device pcie-root-port,id=p1 " "-device pcie-pci-bridge,bus=p1,id=b1"); @@ -395,6 +450,11 @@ static void test_blockdev_add_device_add_and_del(void) const char *arch = qtest_get_arch(); const char *machine_addition = ""; + if (!has_device_builtin("virtio-blk")) { + g_test_skip("Device virtio-blk is not available"); + return; + } + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { machine_addition = "-machine pc"; } @@ -417,6 +477,11 @@ static void test_blockdev_add_device_add_and_del_q35(void) { QTestState *qts; + if (!has_device_builtin("virtio-blk")) { + g_test_skip("Device virtio-blk is not available"); + return; + } + qts = qtest_init("-machine q35 -device pcie-root-port,id=p1 " "-device pcie-pci-bridge,bus=p1,id=b1"); diff --git a/tests/qtest/fuzz-lsi53c895a-test.c b/tests/qtest/fuzz-lsi53c895a-test.c index 392a7ae7ed..a9254b455d 100644 --- a/tests/qtest/fuzz-lsi53c895a-test.c +++ b/tests/qtest/fuzz-lsi53c895a-test.c @@ -112,6 +112,10 @@ static void test_lsi_do_dma_empty_queue(void) int main(int argc, char **argv) { + if (!qtest_has_device("lsi53c895a")) { + return 0; + } + g_test_init(&argc, &argv, NULL); qtest_add_func("fuzz/lsi53c895a/lsi_do_dma_empty_queue", diff --git a/tests/qtest/hd-geo-test.c b/tests/qtest/hd-geo-test.c index 4a7628077b..5aa258a2b3 100644 --- a/tests/qtest/hd-geo-test.c +++ b/tests/qtest/hd-geo-test.c @@ -1090,30 +1090,42 @@ int main(int argc, char **argv) qtest_add_func("hd-geo/override/ide", test_override_ide); if (qtest_has_device("lsi53c895a")) { qtest_add_func("hd-geo/override/scsi", test_override_scsi); - qtest_add_func("hd-geo/override/scsi_2_controllers", - test_override_scsi_2_controllers); + if (qtest_has_device("virtio-scsi-pci")) { + qtest_add_func("hd-geo/override/scsi_2_controllers", + test_override_scsi_2_controllers); + } } - qtest_add_func("hd-geo/override/virtio_blk", test_override_virtio_blk); qtest_add_func("hd-geo/override/zero_chs", test_override_zero_chs); - qtest_add_func("hd-geo/override/scsi_hot_unplug", - test_override_scsi_hot_unplug); - qtest_add_func("hd-geo/override/virtio_hot_unplug", - test_override_virtio_hot_unplug); + if (qtest_has_device("virtio-scsi-pci")) { + qtest_add_func("hd-geo/override/scsi_hot_unplug", + test_override_scsi_hot_unplug); + } + if (qtest_has_device("virtio-blk-pci")) { + qtest_add_func("hd-geo/override/virtio_hot_unplug", + test_override_virtio_hot_unplug); + qtest_add_func("hd-geo/override/virtio_blk", + test_override_virtio_blk); + } if (qtest_has_machine("q35")) { qtest_add_func("hd-geo/override/sata", test_override_sata); - qtest_add_func("hd-geo/override/virtio_blk_q35", - test_override_virtio_blk_q35); qtest_add_func("hd-geo/override/zero_chs_q35", test_override_zero_chs_q35); if (qtest_has_device("lsi53c895a")) { qtest_add_func("hd-geo/override/scsi_q35", test_override_scsi_q35); } - qtest_add_func("hd-geo/override/scsi_hot_unplug_q35", - test_override_scsi_hot_unplug_q35); - qtest_add_func("hd-geo/override/virtio_hot_unplug_q35", - test_override_virtio_hot_unplug_q35); + if (qtest_has_device("virtio-scsi-pci")) { + qtest_add_func("hd-geo/override/scsi_hot_unplug_q35", + test_override_scsi_hot_unplug_q35); + } + if (qtest_has_device("virtio-blk-pci")) { + qtest_add_func("hd-geo/override/virtio_hot_unplug_q35", + test_override_virtio_hot_unplug_q35); + qtest_add_func("hd-geo/override/virtio_blk_q35", + test_override_virtio_blk_q35); + } + } } else { g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; " diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index e97616d327..222e1892fb 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -73,11 +73,14 @@ qtests_i386 = \ (config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \ (config_host.has_key('CONFIG_POSIX') and \ config_all_devices.has_key('CONFIG_ACPI_ERST') ? ['erst-test'] : []) + \ - (config_all_devices.has_key('CONFIG_VIRTIO_NET') and \ + (config_all_devices.has_key('CONFIG_PCIE_PORT') and \ + config_all_devices.has_key('CONFIG_VIRTIO_NET') and \ config_all_devices.has_key('CONFIG_Q35') and \ config_all_devices.has_key('CONFIG_VIRTIO_PCI') and \ slirp.found() ? ['virtio-net-failover'] : []) + \ - (unpack_edk2_blobs ? ['bios-tables-test'] : []) + \ + (unpack_edk2_blobs and \ + config_all_devices.has_key('CONFIG_HPET') and \ + config_all_devices.has_key('CONFIG_PARALLEL') ? ['bios-tables-test'] : []) + \ qtests_pci + \ qtests_cxl + \ ['fdc-test', @@ -196,11 +199,11 @@ qtests_arm = \ (config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \ (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \ (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \ + (config_all_devices.has_key('CONFIG_GENERIC_LOADER') ? ['hexloader-test'] : []) + \ ['arm-cpu-features', 'microbit-test', 'test-arm-mptimer', - 'boot-serial-test', - 'hexloader-test'] + 'boot-serial-test'] # TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional qtests_aarch64 = \ @@ -254,10 +257,14 @@ qos_test_ss.add( 'virtio-net-test.c', 'virtio-rng-test.c', 'virtio-scsi-test.c', - 'virtio-serial-test.c', 'virtio-iommu-test.c', 'vmxnet3-test.c', ) + +if config_all_devices.has_key('CONFIG_VIRTIO_SERIAL') + qos_test_ss.add(files('virtio-serial-test.c')) +endif + if config_host.has_key('CONFIG_POSIX') qos_test_ss.add(files('e1000e-test.c')) endif diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c index e320a625c4..ea4ca1d106 100644 --- a/tests/qtest/npcm7xx_pwm-test.c +++ b/tests/qtest/npcm7xx_pwm-test.c @@ -20,6 +20,8 @@ #include "qapi/qmp/qdict.h" #include "qapi/qmp/qnum.h" +static int verbosity_level; + #define REF_HZ 25000000 /* Register field definitions. */ @@ -221,7 +223,9 @@ static uint64_t pwm_qom_get(QTestState *qts, const char *path, const char *name) QDict *response; uint64_t val; - g_test_message("Getting properties %s from %s", name, path); + if (verbosity_level >= 2) { + g_test_message("Getting properties %s from %s", name, path); + } response = qtest_qmp(qts, "{ 'execute': 'qom-get'," " 'arguments': { 'path': %s, 'property': %s}}", path, name); @@ -260,8 +264,10 @@ static void mft_qom_set(QTestState *qts, int index, const char *name, QDict *response; char *path = g_strdup_printf("/machine/soc/mft[%d]", index); - g_test_message("Setting properties %s of mft[%d] with value %u", - name, index, value); + if (verbosity_level >= 2) { + g_test_message("Setting properties %s of mft[%d] with value %u", + name, index, value); + } response = qtest_qmp(qts, "{ 'execute': 'qom-set'," " 'arguments': { 'path': %s, " " 'property': %s, 'value': %u}}", @@ -506,9 +512,12 @@ static void mft_verify_rpm(QTestState *qts, const TestData *td, uint64_t duty) int32_t expected_cnt = mft_compute_cnt(rpm, clk); qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic"); - g_test_message( - "verifying rpm for mft[%d]: clk: %" PRIu64 ", duty: %" PRIu64 ", rpm: %u, cnt: %d", - index, clk, duty, rpm, expected_cnt); + if (verbosity_level >= 2) { + g_test_message( + "verifying rpm for mft[%d]: clk: %" PRIu64 ", duty: %" PRIu64 + ", rpm: %u, cnt: %d", + index, clk, duty, rpm, expected_cnt); + } /* Verify rpm for fan A */ /* Stop capture */ @@ -670,6 +679,12 @@ int main(int argc, char **argv) { TestData test_data_list[ARRAY_SIZE(pwm_module_list) * ARRAY_SIZE(pwm_list)]; + char *v_env = getenv("V"); + + if (v_env) { + verbosity_level = atoi(v_env); + } + g_test_init(&argc, &argv, NULL); for (int i = 0; i < ARRAY_SIZE(pwm_module_list); ++i) { diff --git a/tests/qtest/pxe-test.c b/tests/qtest/pxe-test.c index 52f0b5c67c..62b6eef464 100644 --- a/tests/qtest/pxe-test.c +++ b/tests/qtest/pxe-test.c @@ -108,6 +108,10 @@ static void test_batch(const testdef_t *tests, bool ipv6) const testdef_t *test = &tests[i]; char *testname; + if (!qtest_has_device(test->model)) { + continue; + } + testname = g_strdup_printf("pxe/ipv4/%s/%s", test->machine, test->model); qtest_add_data_func(testname, test, test_pxe_ipv4); diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target index a34fa68473..50c1b88065 100644 --- a/tests/tcg/s390x/Makefile.softmmu-target +++ b/tests/tcg/s390x/Makefile.softmmu-target @@ -3,7 +3,7 @@ VPATH+=$(S390X_SRC) QEMU_OPTS=-action panic=exit-failure -kernel %: %.S - $(CC) -march=z13 -m64 -nostartfiles -static -Wl,-Ttext=0 \ + $(CC) -march=z13 -m64 -nostdlib -static -Wl,-Ttext=0 \ -Wl,--build-id=none $< -o $@ TESTS += unaligned-lowcore diff --git a/tests/unit/test-xbzrle.c b/tests/unit/test-xbzrle.c index ef951b6e54..547046d093 100644 --- a/tests/unit/test-xbzrle.c +++ b/tests/unit/test-xbzrle.c @@ -16,6 +16,35 @@ #define XBZRLE_PAGE_SIZE 4096 +int (*xbzrle_encode_buffer_func)(uint8_t *, uint8_t *, int, + uint8_t *, int) = xbzrle_encode_buffer; +#if defined(CONFIG_AVX512BW_OPT) +#include "qemu/cpuid.h" +static void __attribute__((constructor)) init_cpu_flag(void) +{ + unsigned max = __get_cpuid_max(0, NULL); + int a, b, c, d; + if (max >= 1) { + __cpuid(1, a, b, c, d); + /* We must check that AVX is not just available, but usable. */ + if ((c & bit_OSXSAVE) && (c & bit_AVX) && max >= 7) { + int bv; + __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0)); + __cpuid_count(7, 0, a, b, c, d); + /* 0xe6: + * XCR0[7:5] = 111b (OPMASK state, upper 256-bit of ZMM0-ZMM15 + * and ZMM16-ZMM31 state are enabled by OS) + * XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS) + */ + if ((bv & 0xe6) == 0xe6 && (b & bit_AVX512BW)) { + xbzrle_encode_buffer_func = xbzrle_encode_buffer_avx512; + } + } + } + return ; +} +#endif + static void test_uleb(void) { uint32_t i, val; @@ -54,7 +83,7 @@ static void test_encode_decode_zero(void) buffer[1000 + diff_len + 5] = 105; /* encode zero page */ - dlen = xbzrle_encode_buffer(buffer, buffer, XBZRLE_PAGE_SIZE, compressed, + dlen = xbzrle_encode_buffer_func(buffer, buffer, XBZRLE_PAGE_SIZE, compressed, XBZRLE_PAGE_SIZE); g_assert(dlen == 0); @@ -78,7 +107,7 @@ static void test_encode_decode_unchanged(void) test[1000 + diff_len + 5] = 109; /* test unchanged buffer */ - dlen = xbzrle_encode_buffer(test, test, XBZRLE_PAGE_SIZE, compressed, + dlen = xbzrle_encode_buffer_func(test, test, XBZRLE_PAGE_SIZE, compressed, XBZRLE_PAGE_SIZE); g_assert(dlen == 0); @@ -96,7 +125,7 @@ static void test_encode_decode_1_byte(void) test[XBZRLE_PAGE_SIZE - 1] = 1; - dlen = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed, + dlen = xbzrle_encode_buffer_func(buffer, test, XBZRLE_PAGE_SIZE, compressed, XBZRLE_PAGE_SIZE); g_assert(dlen == (uleb128_encode_small(&buf[0], 4095) + 2)); @@ -121,7 +150,7 @@ static void test_encode_decode_overflow(void) } /* encode overflow */ - rc = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed, + rc = xbzrle_encode_buffer_func(buffer, test, XBZRLE_PAGE_SIZE, compressed, XBZRLE_PAGE_SIZE); g_assert(rc == -1); @@ -152,7 +181,7 @@ static void encode_decode_range(void) test[1000 + diff_len + 5] = 109; /* test encode/decode */ - dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, compressed, + dlen = xbzrle_encode_buffer_func(test, buffer, XBZRLE_PAGE_SIZE, compressed, XBZRLE_PAGE_SIZE); rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE); |