On 23.01.2013, at 11:01, Andreas Färber wrote: > 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 &&
I don't think we will be able to find a common dominator for hypercall ABIs across the board. So this one should be called s390_kvm_hypercall, as that's what you are really modeling :). Alex > + 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 >