qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC 1/3] qtest: Prepare hypercall support


From: Anthony Liguori
Subject: Re: [Qemu-devel] [RFC 1/3] qtest: Prepare hypercall support
Date: Wed, 23 Jan 2013 06:55:10 -0600
User-agent: Notmuch/0.13.2+93~ged93d79 (http://notmuchmail.org) Emacs/23.3.1 (x86_64-pc-linux-gnu)

Andreas Färber <address@hidden> writes:

> 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);

Certainly on x86 hypercalls have a well defined set of arguments.  I
seem to recall having this discussion with David and Paul though and
with PAPR, not all hypercalls follow the same conventions in terms of
what registers are used.

David, can you elaborate?  Am I remembering incorrectly?

Regards,

Anthony Liguori

>      } 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]