From: Greg Kurz <groug@kaod.org>
To: Laurent Vivier <lvivier@redhat.com>
Cc: qemu-devel@nongnu.org, David Gibson <david@gibson.dropbear.id.au>,
Peter Maydell <peter.maydell@linaro.org>
Subject: Re: [Qemu-devel] [PATCH] qtest: ask endianness of the target in qtest_init()
Date: Thu, 6 Oct 2016 22:46:22 +0200 [thread overview]
Message-ID: <20161006224622.516cee20@bahia> (raw)
In-Reply-To: <1475780218-26393-1-git-send-email-lvivier@redhat.com>
On Thu, 6 Oct 2016 20:56:58 +0200
Laurent Vivier <lvivier@redhat.com> wrote:
> The target endianness is not deduced anymore from
> the architecture name but asked directly to the guest,
> using a new qtest command: "endianness". As it can't
> change (this is the value of TARGET_WORDS_BIGENDIAN),
> we store it to not have to ask every time we want to
> know if we have to byte-swap a value.
>
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> CC: Greg Kurz <groug@kaod.org>
> CC: David Gibson <david@gibson.dropbear.id.au>
> CC: Peter Maydell <peter.maydell@linaro.org>
> ---
> Note: this patch can be seen as a v2 of
> "qtest: evaluate endianness of the target in qtest_init()"
> from the patch series "tests: enable virtio tests on SPAPR"
> in which I have added the idea from Peter to ask the endianness
> directly to the guest using a new qtest command.
>
This is definitely an improvement indeed.
Reviewed-by: Greg Kurz <groug@kaod.org>
> qtest.c | 7 ++
> tests/libqos/virtio-pci.c | 2 +-
> tests/libqtest.c | 224 ++++++++++++++++++++--------------------------
> tests/libqtest.h | 16 +++-
> tests/virtio-blk-test.c | 2 +-
> 5 files changed, 118 insertions(+), 133 deletions(-)
>
> diff --git a/qtest.c b/qtest.c
> index 22482cc..b53b39c 100644
> --- a/qtest.c
> +++ b/qtest.c
> @@ -537,6 +537,13 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
>
> qtest_send_prefix(chr);
> qtest_send(chr, "OK\n");
> + } else if (strcmp(words[0], "endianness") == 0) {
> + qtest_send_prefix(chr);
> +#if defined(TARGET_WORDS_BIGENDIAN)
> + qtest_sendf(chr, "OK big\n");
> +#else
> + qtest_sendf(chr, "OK little\n");
> +#endif
> #ifdef TARGET_PPC64
> } else if (strcmp(words[0], "rtas") == 0) {
> uint64_t res, args, ret;
> diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
> index 18b92b9..6e005c1 100644
> --- a/tests/libqos/virtio-pci.c
> +++ b/tests/libqos/virtio-pci.c
> @@ -86,7 +86,7 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
> int i;
> uint64_t u64 = 0;
>
> - if (qtest_big_endian()) {
> + if (target_big_endian()) {
> for (i = 0; i < 8; ++i) {
> u64 |= (uint64_t)qpci_io_readb(dev->pdev,
> (void *)(uintptr_t)addr + i) << (7 - i) * 8;
> diff --git a/tests/libqtest.c b/tests/libqtest.c
> index 6f6bdf1..27cf6b1 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -37,6 +37,7 @@ struct QTestState
> bool irq_level[MAX_IRQ];
> GString *rx;
> pid_t qemu_pid; /* our child QEMU process */
> + bool big_endian;
> };
>
> static GHookList abrt_hooks;
> @@ -146,89 +147,6 @@ void qtest_add_abrt_handler(GHookFunc fn, const void *data)
> g_hook_prepend(&abrt_hooks, hook);
> }
>
> -QTestState *qtest_init(const char *extra_args)
> -{
> - QTestState *s;
> - int sock, qmpsock, i;
> - gchar *socket_path;
> - gchar *qmp_socket_path;
> - gchar *command;
> - const char *qemu_binary;
> -
> - qemu_binary = getenv("QTEST_QEMU_BINARY");
> - g_assert(qemu_binary != NULL);
> -
> - s = g_malloc(sizeof(*s));
> -
> - socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
> - qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
> -
> - sock = init_socket(socket_path);
> - qmpsock = init_socket(qmp_socket_path);
> -
> - qtest_add_abrt_handler(kill_qemu_hook_func, s);
> -
> - s->qemu_pid = fork();
> - if (s->qemu_pid == 0) {
> - setenv("QEMU_AUDIO_DRV", "none", true);
> - command = g_strdup_printf("exec %s "
> - "-qtest unix:%s,nowait "
> - "-qtest-log %s "
> - "-qmp unix:%s,nowait "
> - "-machine accel=qtest "
> - "-display none "
> - "%s", qemu_binary, socket_path,
> - getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null",
> - qmp_socket_path,
> - extra_args ?: "");
> - execlp("/bin/sh", "sh", "-c", command, NULL);
> - exit(1);
> - }
> -
> - s->fd = socket_accept(sock);
> - if (s->fd >= 0) {
> - s->qmp_fd = socket_accept(qmpsock);
> - }
> - unlink(socket_path);
> - unlink(qmp_socket_path);
> - g_free(socket_path);
> - g_free(qmp_socket_path);
> -
> - g_assert(s->fd >= 0 && s->qmp_fd >= 0);
> -
> - s->rx = g_string_new("");
> - for (i = 0; i < MAX_IRQ; i++) {
> - s->irq_level[i] = false;
> - }
> -
> - /* Read the QMP greeting and then do the handshake */
> - qtest_qmp_discard_response(s, "");
> - qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }");
> -
> - if (getenv("QTEST_STOP")) {
> - kill(s->qemu_pid, SIGSTOP);
> - }
> -
> - return s;
> -}
> -
> -void qtest_quit(QTestState *s)
> -{
> - qtest_instances = g_list_remove(qtest_instances, s);
> - g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s));
> -
> - /* Uninstall SIGABRT handler on last instance */
> - if (!qtest_instances) {
> - cleanup_sigabrt_handler();
> - }
> -
> - kill_qemu(s);
> - close(s->fd);
> - close(s->qmp_fd);
> - g_string_free(s->rx, true);
> - g_free(s);
> -}
> -
> static void socket_send(int fd, const char *buf, size_t size)
> {
> size_t offset;
> @@ -347,6 +265,99 @@ typedef struct {
> QDict *response;
> } QMPResponseParser;
>
> +QTestState *qtest_init(const char *extra_args)
> +{
> + QTestState *s;
> + int sock, qmpsock, i;
> + gchar *socket_path;
> + gchar *qmp_socket_path;
> + gchar *command;
> + const char *qemu_binary;
> + gchar **args;
> +
> + qemu_binary = getenv("QTEST_QEMU_BINARY");
> + g_assert(qemu_binary != NULL);
> +
> + s = g_malloc(sizeof(*s));
> +
> + socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
> + qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
> +
> + sock = init_socket(socket_path);
> + qmpsock = init_socket(qmp_socket_path);
> +
> + qtest_add_abrt_handler(kill_qemu_hook_func, s);
> +
> + s->qemu_pid = fork();
> + if (s->qemu_pid == 0) {
> + setenv("QEMU_AUDIO_DRV", "none", true);
> + command = g_strdup_printf("exec %s "
> + "-qtest unix:%s,nowait "
> + "-qtest-log %s "
> + "-qmp unix:%s,nowait "
> + "-machine accel=qtest "
> + "-display none "
> + "%s", qemu_binary, socket_path,
> + getenv("QTEST_LOG") ? "/dev/fd/2"
> + : "/dev/null",
> + qmp_socket_path,
> + extra_args ?: "");
> + execlp("/bin/sh", "sh", "-c", command, NULL);
> + exit(1);
> + }
> +
> + s->fd = socket_accept(sock);
> + if (s->fd >= 0) {
> + s->qmp_fd = socket_accept(qmpsock);
> + }
> + unlink(socket_path);
> + unlink(qmp_socket_path);
> + g_free(socket_path);
> + g_free(qmp_socket_path);
> +
> + g_assert(s->fd >= 0 && s->qmp_fd >= 0);
> +
> + s->rx = g_string_new("");
> + for (i = 0; i < MAX_IRQ; i++) {
> + s->irq_level[i] = false;
> + }
> +
> + /* Read the QMP greeting and then do the handshake */
> + qtest_qmp_discard_response(s, "");
> + qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }");
> +
> + if (getenv("QTEST_STOP")) {
> + kill(s->qemu_pid, SIGSTOP);
> + }
> +
> + /* ask endianness of the target */
> +
> + qtest_sendf(s, "endianness\n");
> + args = qtest_rsp(s, 1);
> + g_assert(strcmp(args[1], "big") == 0 || strcmp(args[1], "little") == 0);
> + s->big_endian = strcmp(args[1], "big") == 0;
> + g_strfreev(args);
> +
> + return s;
> +}
> +
> +void qtest_quit(QTestState *s)
> +{
> + qtest_instances = g_list_remove(qtest_instances, s);
> + g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s));
> +
> + /* Uninstall SIGABRT handler on last instance */
> + if (!qtest_instances) {
> + cleanup_sigabrt_handler();
> + }
> +
> + kill_qemu(s);
> + close(s->fd);
> + close(s->qmp_fd);
> + g_string_free(s->rx, true);
> + g_free(s);
> +}
> +
> static void qmp_response(JSONMessageParser *parser, GQueue *tokens)
> {
> QMPResponseParser *qmp = container_of(parser, QMPResponseParser, parser);
> @@ -886,50 +897,7 @@ char *hmp(const char *fmt, ...)
> return ret;
> }
>
> -bool qtest_big_endian(void)
> +bool qtest_big_endian(QTestState *s)
> {
> - const char *arch = qtest_get_arch();
> - int i;
> -
> - static const struct {
> - const char *arch;
> - bool big_endian;
> - } endianness[] = {
> - { "aarch64", false },
> - { "alpha", false },
> - { "arm", false },
> - { "cris", false },
> - { "i386", false },
> - { "lm32", true },
> - { "m68k", true },
> - { "microblaze", true },
> - { "microblazeel", false },
> - { "mips", true },
> - { "mips64", true },
> - { "mips64el", false },
> - { "mipsel", false },
> - { "moxie", true },
> - { "or32", true },
> - { "ppc", true },
> - { "ppc64", true },
> - { "ppcemb", true },
> - { "s390x", true },
> - { "sh4", false },
> - { "sh4eb", true },
> - { "sparc", true },
> - { "sparc64", true },
> - { "unicore32", false },
> - { "x86_64", false },
> - { "xtensa", false },
> - { "xtensaeb", true },
> - {},
> - };
> -
> - for (i = 0; endianness[i].arch; i++) {
> - if (strcmp(endianness[i].arch, arch) == 0) {
> - return endianness[i].big_endian;
> - }
> - }
> -
> - return false;
> + return s->big_endian;
> }
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index f7402e0..4be1f77 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -410,6 +410,14 @@ int64_t qtest_clock_step(QTestState *s, int64_t step);
> int64_t qtest_clock_set(QTestState *s, int64_t val);
>
> /**
> + * qtest_big_endian:
> + * @s: QTestState instance to operate on.
> + *
> + * Returns: True if the architecture under test has a big endian configuration.
> + */
> +bool qtest_big_endian(QTestState *s);
> +
> +/**
> * qtest_get_arch:
> *
> * Returns: The architecture for the QEMU executable under test.
> @@ -874,12 +882,14 @@ static inline int64_t clock_set(int64_t val)
> }
>
> /**
> - * qtest_big_endian:
> + * target_big_endian:
> *
> * Returns: True if the architecture under test has a big endian configuration.
> */
> -bool qtest_big_endian(void);
> -
> +static inline bool target_big_endian(void)
> +{
> + return qtest_big_endian(global_qtest);
> +}
>
> QDict *qmp_fd_receive(int fd);
> void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
> diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
> index 3c4fecc..0506917 100644
> --- a/tests/virtio-blk-test.c
> +++ b/tests/virtio-blk-test.c
> @@ -125,7 +125,7 @@ static inline void virtio_blk_fix_request(QVirtioBlkReq *req)
> bool host_endian = false;
> #endif
>
> - if (qtest_big_endian() != host_endian) {
> + if (target_big_endian() != host_endian) {
> req->type = bswap32(req->type);
> req->ioprio = bswap32(req->ioprio);
> req->sector = bswap64(req->sector);
next prev parent reply other threads:[~2016-10-06 20:46 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-06 18:56 [Qemu-devel] [PATCH] qtest: ask endianness of the target in qtest_init() Laurent Vivier
2016-10-06 20:45 ` Peter Maydell
2016-10-07 7:10 ` Laurent Vivier
2016-10-07 7:31 ` Greg Kurz
2016-10-07 9:36 ` Peter Maydell
2016-10-07 9:57 ` Greg Kurz
2016-10-06 20:46 ` Greg Kurz [this message]
2016-10-06 23:55 ` David Gibson
2016-10-07 7:14 ` Greg Kurz
2016-10-07 9:39 ` Peter Maydell
2016-10-07 10:10 ` Greg Kurz
2016-10-10 1:30 ` David Gibson
2016-10-10 1:28 ` David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161006224622.516cee20@bahia \
--to=groug@kaod.org \
--cc=david@gibson.dropbear.id.au \
--cc=lvivier@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).