diff options
| author | Stefan Hajnoczi <stefanha@redhat.com> | 2025-02-10 13:26:17 -0500 |
|---|---|---|
| committer | Stefan Hajnoczi <stefanha@redhat.com> | 2025-02-10 13:26:17 -0500 |
| commit | ffaf7f0376f8040ce9068d71ae9ae8722505c42e (patch) | |
| tree | c84be244b60ee3e1f96cb858bad1a1589a586c98 /system/qtest.c | |
| parent | f2ec48fefd172a8dd20cb0073087d659aca9578c (diff) | |
| parent | 24c61663dcec0e87bb4206a7623f0e222e188b47 (diff) | |
| download | focaccia-qemu-ffaf7f0376f8040ce9068d71ae9ae8722505c42e.tar.gz focaccia-qemu-ffaf7f0376f8040ce9068d71ae9ae8722505c42e.zip | |
Merge tag 'pull-10.0-testing-and-gdstub-updates-100225-1' of https://gitlab.com/stsquad/qemu into staging
testing and gdbstub updates: - add a check-rust test to docker builds - re-factor the qtest logic to be cleaner - fix tests to not clock_step when no timers enabled - roll-up log prefix into qtest_send - cleaner error reporting when qtest_clock_set fails - revert old deadlock fix now tests are updated - only run full set of migration tests under HW acceleration - support late attachment to user-mode gdbstubs # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmeqBSsACgkQ+9DbCVqe # KkQS/Af+K0hpdGc1msiuMsqmuESBvhoQniYZFLN1/pwe2KpG8i/+fq2fsCuxJhJ1 # 2TzPH7aj54p9MGCZf2k9JLhO22XldN+oezZMc1crhoWK0AtrWhnLs58I2oEPIsUo # NmGO6Zfm98ge89o2y8GCvd0QXAtUf+jduDKnW0mfnOnw+w/mky5KzWS7/1091VGW # 42LSY4KnqgdLSqLyuLBOrgADEjB1ChWS4/bSC+kEYSGrmNQB+n1KeIzzlJBGpOr0 # Z9yzmhMCm7TWdkFNPmnVfYH/7ZUNcpv6PtQSpkku4f6b/gybyvJBknHpM4i+Gpb5 # 87wSjljrCpdNm/9KFRjiJuUWdS/jCg== # =UF0n # -----END PGP SIGNATURE----- # gpg: Signature made Mon 10 Feb 2025 08:54:51 EST # gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44 * tag 'pull-10.0-testing-and-gdstub-updates-100225-1' of https://gitlab.com/stsquad/qemu: tests/tcg: Add late gdbstub attach test docs/user: Document the %d placeholder and suspend=n QEMU_GDB features gdbstub: Allow late attachment osdep: Introduce qemu_kill_thread() user: Introduce host_interrupt_signal user: Introduce user/signal.h gdbstub: Try unlinking the unix socket before binding gdbstub: Allow the %d placeholder in the socket path tests/qtest/migration: Pick smoke tests tests/qtest/migration: Add --full option Revert "util/timer: avoid deadlock when shutting down" tests/qtest: tighten up the checks on clock_step tests/qtest: rename qtest_send_prefix and roll-up into qtest_send tests/qtest: simplify qtest_process_inbuf tests/qtest: don't step clock at start of npcm7xx periodic IRQ test tests/qtest: don't attempt to clock_step while waiting for virtio ISR tests/docker: replicate the check-rust-tools-nightly CI job Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'system/qtest.c')
| -rw-r--r-- | system/qtest.c | 59 |
1 files changed, 22 insertions, 37 deletions
diff --git a/system/qtest.c b/system/qtest.c index e68ed0f2a8..12152efbcd 100644 --- a/system/qtest.c +++ b/system/qtest.c @@ -265,7 +265,7 @@ static int hex2nib(char ch) } } -void qtest_send_prefix(CharBackend *chr) +static void qtest_log_timestamp(void) { if (!qtest_log_fp || !qtest_opened) { return; @@ -282,7 +282,7 @@ static void G_GNUC_PRINTF(1, 2) qtest_log_send(const char *fmt, ...) return; } - qtest_send_prefix(NULL); + qtest_log_timestamp(); va_start(ap, fmt); vfprintf(qtest_log_fp, fmt, ap); @@ -301,6 +301,7 @@ static void qtest_server_char_be_send(void *opaque, const char *str) static void qtest_send(CharBackend *chr, const char *str) { + qtest_log_timestamp(); qtest_server_send(qtest_server_send_opaque, str); } @@ -324,7 +325,6 @@ static void qtest_irq_handler(void *opaque, int n, int level) if (irq_levels[n] != level) { CharBackend *chr = &qtest->qtest_chr; irq_levels[n] = level; - qtest_send_prefix(chr); qtest_sendf(chr, "IRQ %s %d\n", level ? "raise" : "lower", n); } @@ -380,19 +380,16 @@ static void qtest_process_command(CharBackend *chr, gchar **words) is_outbound = words[0][14] == 'o'; dev = DEVICE(object_resolve_path(words[1], NULL)); if (!dev) { - qtest_send_prefix(chr); qtest_send(chr, "FAIL Unknown device\n"); return; } if (is_named && !is_outbound) { - qtest_send_prefix(chr); qtest_send(chr, "FAIL Interception of named in-GPIOs not yet supported\n"); return; } if (irq_intercept_dev) { - qtest_send_prefix(chr); if (irq_intercept_dev != dev) { qtest_send(chr, "FAIL IRQ intercept already enabled\n"); } else { @@ -419,7 +416,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) } } - qtest_send_prefix(chr); if (interception_succeeded) { irq_intercept_dev = dev; qtest_send(chr, "OK\n"); @@ -438,7 +434,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) dev = DEVICE(object_resolve_path(words[1], NULL)); if (!dev) { - qtest_send_prefix(chr); qtest_send(chr, "FAIL Unknown device\n"); return; } @@ -457,7 +452,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) irq = qdev_get_gpio_in_named(dev, name, num); qemu_set_irq(irq, level); - qtest_send_prefix(chr); qtest_send(chr, "OK\n"); } else if (strcmp(words[0], "outb") == 0 || strcmp(words[0], "outw") == 0 || @@ -480,7 +474,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) } else if (words[0][3] == 'l') { cpu_outl(addr, value); } - qtest_send_prefix(chr); qtest_send(chr, "OK\n"); } else if (strcmp(words[0], "inb") == 0 || strcmp(words[0], "inw") == 0 || @@ -501,7 +494,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) } else if (words[0][2] == 'l') { value = cpu_inl(addr); } - qtest_send_prefix(chr); qtest_sendf(chr, "OK 0x%04x\n", value); } else if (strcmp(words[0], "writeb") == 0 || strcmp(words[0], "writew") == 0 || @@ -537,7 +529,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &data, 8); } - qtest_send_prefix(chr); qtest_send(chr, "OK\n"); } else if (strcmp(words[0], "readb") == 0 || strcmp(words[0], "readw") == 0 || @@ -571,7 +562,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) &value, 8); tswap64s(&value); } - qtest_send_prefix(chr); qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value); } else if (strcmp(words[0], "read") == 0) { g_autoptr(GString) enc = NULL; @@ -593,7 +583,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) enc = qemu_hexdump_line(NULL, data, len, 0, 0); - qtest_send_prefix(chr); qtest_sendf(chr, "OK 0x%s\n", enc->str); g_free(data); @@ -613,7 +602,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data, len); b64_data = g_base64_encode(data, len); - qtest_send_prefix(chr); qtest_sendf(chr, "OK %s\n", b64_data); g_free(data); @@ -649,7 +637,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) len); g_free(data); - qtest_send_prefix(chr); qtest_send(chr, "OK\n"); } else if (strcmp(words[0], "memset") == 0) { uint64_t addr, len; @@ -673,7 +660,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) g_free(data); } - qtest_send_prefix(chr); qtest_send(chr, "OK\n"); } else if (strcmp(words[0], "b64write") == 0) { uint64_t addr, len; @@ -705,10 +691,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words) address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data, len); - qtest_send_prefix(chr); qtest_send(chr, "OK\n"); } else if (strcmp(words[0], "endianness") == 0) { - qtest_send_prefix(chr); if (target_words_bigendian()) { qtest_sendf(chr, "OK big\n"); } else { @@ -724,17 +708,24 @@ static void qtest_process_command(CharBackend *chr, gchar **words) } else { ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, QEMU_TIMER_ATTR_ALL); + if (ns < 0) { + qtest_send(chr, "FAIL " + "cannot advance clock to the next deadline " + "because there is no pending deadline\n"); + return; + } } new_ns = qemu_clock_advance_virtual_time(old_ns + ns); - qtest_send_prefix(chr); - qtest_sendf(chr, "%s %"PRIi64"\n", - new_ns > old_ns ? "OK" : "FAIL", new_ns); + if (new_ns > old_ns) { + qtest_sendf(chr, "OK %"PRIi64"\n", new_ns); + } else { + qtest_sendf(chr, "FAIL could not advance time\n"); + } } else if (strcmp(words[0], "module_load") == 0) { Error *local_err = NULL; int rv; g_assert(words[1] && words[2]); - qtest_send_prefix(chr); rv = module_load(words[1], words[2], &local_err); if (rv > 0) { qtest_sendf(chr, "OK\n"); @@ -752,36 +743,30 @@ static void qtest_process_command(CharBackend *chr, gchar **words) ret = qemu_strtoi64(words[1], NULL, 0, &ns); g_assert(ret == 0); new_ns = qemu_clock_advance_virtual_time(ns); - qtest_send_prefix(chr); qtest_sendf(chr, "%s %"PRIi64"\n", new_ns == ns ? "OK" : "FAIL", new_ns); } else if (process_command_cb && process_command_cb(chr, words)) { /* Command got consumed by the callback handler */ } else { - qtest_send_prefix(chr); qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]); } } +/* + * Process as much of @inbuf as we can in newline terminated chunks. + * Remove the processed commands from @inbuf as we go. + */ static void qtest_process_inbuf(CharBackend *chr, GString *inbuf) { char *end; while ((end = strchr(inbuf->str, '\n')) != NULL) { - size_t offset; - GString *cmd; - gchar **words; - - offset = end - inbuf->str; + size_t len = end - inbuf->str; + g_autofree char *cmd = g_strndup(inbuf->str, len); + g_auto(GStrv) words = g_strsplit(cmd, " ", 0); - cmd = g_string_new_len(inbuf->str, offset); - g_string_erase(inbuf, 0, offset + 1); - - words = g_strsplit(cmd->str, " ", 0); + g_string_erase(inbuf, 0, len + 1); qtest_process_command(chr, words); - g_strfreev(words); - - g_string_free(cmd, TRUE); } } |