[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 1/3] qtest: Prepare hypercall support
From: |
Andreas Färber |
Subject: |
[Qemu-devel] [RFC 1/3] qtest: Prepare hypercall support |
Date: |
Wed, 23 Jan 2013 11:01:52 +0100 |
Signed-off-by: Andreas Färber <address@hidden>
---
include/sysemu/qtest.h | 2 ++
qtest.c | 26 ++++++++++++++++++++++++++
stubs/Makefile.objs | 1 +
stubs/qtest.c | 12 ++++++++++++
tests/libqtest.c | 21 +++++++++++++++++++++
tests/libqtest.h | 17 +++++++++++++++++
6 Dateien geändert, 79 Zeilen hinzugefügt(+)
create mode 100644 stubs/qtest.c
diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index 723a4f9..75ab29d 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -32,6 +32,8 @@ static inline int qtest_available(void)
}
int qtest_init(void);
+bool qtest_hypercall_supported(void);
+int qtest_hypercall(uint64_t code, uint64_t *args);
#else
static inline bool qtest_enabled(void)
{
diff --git a/qtest.c b/qtest.c
index c9b58ce..a5b54e3 100644
--- a/qtest.c
+++ b/qtest.c
@@ -117,6 +117,11 @@ static bool qtest_opened;
* where NUM is an IRQ number. For the PC, interrupts can be intercepted
* simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
* NUM=0 even though it is remapped to GSI 2).
+ *
+ * Hypercalls:
+ *
+ * > hypercall CODE
+ * < OK
*/
static int hex2nib(char ch)
@@ -344,6 +349,27 @@ static void qtest_process_command(CharDriverState *chr,
gchar **words)
qtest_clock_warp(ns);
qtest_send_prefix(chr);
qtest_send(chr, "OK %"PRIi64"\n",
(int64_t)qemu_get_clock_ns(vm_clock));
+ } else if (strcmp(words[0], "hypercall") == 0 &&
+ qtest_hypercall_supported()) {
+ uint64_t code;
+ uint64_t args[13];
+ int ret, i;
+
+ g_assert(words[1] != NULL);
+ code = strtoull(words[1], NULL, 0);
+
+ memset(args, 0, sizeof(args));
+ for (i = 0; i < 13 && words[2 + i] != NULL; i++) {
+ args[i] = strtoull(words[2 + i], NULL, 0);
+ }
+
+ ret = qtest_hypercall(code, args);
+ qtest_send_prefix(chr);
+ if (ret < 0) {
+ qtest_send(chr, "ERR 0x%x\n", ret);
+ return;
+ }
+ qtest_send(chr, "OK 0x%x\n", ret);
} else {
qtest_send_prefix(chr);
qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index a260394..50fb2a7 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -15,6 +15,7 @@ stub-obj-y += mon-printf.o
stub-obj-y += mon-print-filename.o
stub-obj-y += mon-protocol-event.o
stub-obj-y += mon-set-error.o
+stub-obj-y += qtest.o
stub-obj-y += reset.o
stub-obj-y += set-fd-handler.o
stub-obj-y += slirp.o
diff --git a/stubs/qtest.c b/stubs/qtest.c
new file mode 100644
index 0000000..8860e4f
--- /dev/null
+++ b/stubs/qtest.c
@@ -0,0 +1,12 @@
+#include "qemu-common.h"
+#include "sysemu/qtest.h"
+
+bool qtest_hypercall_supported(void)
+{
+ return false;
+}
+
+int qtest_hypercall(uint64_t code, uint64_t *args)
+{
+ return -EINVAL;
+}
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 913fa05..5eb9521 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -476,3 +476,24 @@ void qtest_memwrite(QTestState *s, uint64_t addr, const
void *data, size_t size)
qtest_sendf(s, "\n");
qtest_rsp(s, 0);
}
+
+uint64_t qtest_hypercall(QTestState *s, uint64_t code, int argc, ...)
+{
+ va_list va;
+ gchar **args;
+ uint64_t resp, arg;
+ int i;
+
+ qtest_sendf(s, "hypercall 0x%" PRIx64, code);
+ va_start(va, argc);
+ for (i = 0; i < argc; i++) {
+ arg = va_arg(va, uint64_t);
+ qtest_sendf(s, " 0x%" PRIx64, arg);
+ }
+ va_end(va);
+ qtest_sendf(s, "\n");
+ args = qtest_rsp(s, 2);
+ resp = g_ascii_strtoull(args[1], NULL, 0);
+ g_strfreev(args);
+ return resp;
+}
diff --git a/tests/libqtest.h b/tests/libqtest.h
index c8ade85..3a5a8f9 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -187,6 +187,15 @@ int64_t qtest_clock_step(QTestState *s, int64_t step);
int64_t qtest_clock_set(QTestState *s, int64_t val);
/**
+ * qtest_hypercall:
+ * @s: QTestState instance to operate on.
+ * @code: Hypercall code to call.
+ *
+ * Peform a hypercall @code on the guest.
+ */
+uint64_t qtest_hypercall(QTestState *s, uint64_t code, int argc, ...);
+
+/**
* qtest_get_arch:
*
* Returns the architecture for the QEMU executable under test.
@@ -349,4 +358,12 @@ void qtest_add_func(const char *str, void (*fn));
*/
#define clock_set(val) qtest_clock_set(global_qtest, val)
+/**
+ * hypercall:
+ * @code: Hypercall code.
+ *
+ * Invokes a hypercall in the guest.
+ */
+#define hypercall(code, argc, ...) qtest_hypercall(global_qtest, code, argc,
## __VA_ARGS__)
+
#endif
--
1.7.10.4