Signed-off-by: Andreas Färber <afaer...@suse.de> --- 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