On 16/02/2024 15.44, Philippe Mathieu-Daudé wrote:
From: Gustavo Romero <gustavo.rom...@linaro.org>

Add qtest for the ivshmem-flat device.

Signed-off-by: Gustavo Romero <gustavo.rom...@linaro.org>
Message-ID: <20231127052024.435743-4-gustavo.rom...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org>
---
  tests/qtest/ivshmem-flat-test.c | 320 ++++++++++++++++++++++++++++++++
  tests/qtest/meson.build         |   2 +
  2 files changed, 322 insertions(+)
  create mode 100644 tests/qtest/ivshmem-flat-test.c

diff --git a/tests/qtest/ivshmem-flat-test.c b/tests/qtest/ivshmem-flat-test.c
new file mode 100644
index 0000000000..5489a0d915
--- /dev/null
+++ b/tests/qtest/ivshmem-flat-test.c
@@ -0,0 +1,320 @@
+/*
+ * Inter-VM Shared Memory Flat Device qtests
+ *
+ * SPDX-FileCopyrightText: 2023 Linaro Ltd.
+ * SPDX-FileContributor: Gustavo Romero <gustavo.rom...@linaro.org>
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ */
+
+#include "ivshmem-utils.h"
+
+#define IVSHMEM_FLAT_MMR_ADDR 0x400FF000
+#define IVSHMEM_FLAT_SHM_ADDR 0x40100000
+#define SHM_SIZE 131072 /* 128k */
+
+static ServerThread thread;
+
+uint32_t *shm_ptr;
+char *shm_rel_path;
+char *server_socket_path;
+
+static void cleanup(void)
+{
+    if (shm_ptr) {
+        munmap(shm_ptr, SHM_SIZE);
+        shm_ptr = NULL;
+    }
+
+    if (shm_rel_path) {
+        shm_unlink(shm_rel_path);
+        shm_rel_path = NULL;
+    }
+
+    if (server_socket_path) {
+        unlink(server_socket_path);
+        server_socket_path = NULL;
+    }
+}
+
+static void abort_handler(void *data)
+{
+    test_ivshmem_server_stop(&thread);
+    cleanup();
+}
+
+/*
+ * Check if exactly 1 positive pulse (low->high->low) on 'irq' IRQ line happens
+ * in 'timeout' second(s). 'irq' must be intercepted using 
qtest_irq_intercept_*
+ * before this function can be used on it. It returns 0 when pulse is detected,
+ * otherwise 1.
+ */
+static int test_ivshmem_flat_irq_positive_pulse(QTestState *qts, int irq,
+                                                int timeout)
+{
+    uint64_t num_raises = 0;
+    uint64_t num_lows = 0;
+    uint64_t end_time;
+
+    end_time = g_get_monotonic_time() + timeout * G_TIME_SPAN_SECOND;
+    do {
+        num_raises = qtest_get_irq_raised_counter(qts, 0);
+        if (num_raises) {
+            num_lows = qtest_get_irq_lowered_counter(qts, 0);
+            /* Check for 1 raise and 1 low IRQ event. */
+            if (num_raises == num_lows && num_lows == 1) {
+                return 0;
+            } else {
+                g_message("%s: Timeout expired", __func__);
+                return 1;
+            }
+        }
+        qtest_clock_step(qts, 10000);
+    } while (g_get_monotonic_time() < end_time);
+
+    return 1;
+}

The timeout stuff looks like it will be quite sensitive to slow CI runners. Timeout is set to 2 seconds in most callers - but on very loaded systems, it can easily happen that a job gets interrupted for two seconds.

I think you should either increase the 2 seconds to something bigger (maybe use a #define for it), or instead of using g_get_monotonic_time(), rather loop a certain number of iterations and use a g_sleep(10000) in the loop body - that will also relax the host CPU while the test waits for QEMU to progress?

+static inline uint32_t read_reg(QTestState *qts, enum Reg reg)
+{
+    uint32_t v;
+
+    qtest_memread(qts, IVSHMEM_FLAT_MMR_ADDR + reg, &v, sizeof(v));
+
+    return v;
+}
+
+static inline void write_reg(QTestState *qts, enum Reg reg, uint32_t v)
+{
+    qtest_memwrite(qts, IVSHMEM_FLAT_MMR_ADDR + reg, &v, sizeof(v));
+}
+
+/*
+ * Setup a test VM with ivshmem-flat device attached, IRQ properly set, and
+ * connected to the ivshmem-server.
+ */
+static QTestState *setup_vm(void)
+{
+    QTestState *qts;
+    const char *cmd_line;
+
+    cmd_line = g_strdup_printf("-machine lm3s6965evb "

Could you please add a check, either in meson.build or in main(), to make sure that the lm3s6965evb machine is really available when running this test? ... it might have been disabled in the build ...

+                               "-chardev socket,path=%s,id=ivshm "
+                               "-device ivshmem-flat,chardev=ivshm,"
+                               
"x-irq-qompath='/machine/unattached/device[1]/nvic/unnamed-gpio-in[0]',"
+                               "x-bus-qompath='/sysbus',shmem-size=%d",
+                               server_socket_path, SHM_SIZE);
+    qts = qtest_init(cmd_line);
+
+    return qts;
+}

 Thomas


Reply via email to