From: Alexander Graf <agraf@suse.de>
To: Greg Kurz <gkurz@linux.vnet.ibm.com>
Cc: kwolf@redhat.com, peter.maydell@linaro.org,
thuth@linux.vnet.ibm.com, mst@redhat.com, marc.zyngier@arm.com,
rusty@rustcorp.com.au, qemu-devel@nongnu.org,
stefanha@redhat.com, cornelia.huck@de.ibm.com,
pbonzini@redhat.com, anthony@codemonkey.ws, afaerber@suse.de
Subject: Re: [Qemu-devel] [PATCH v6 1/8] virtio_legacy_get_byteswap: endian-ambivalent targets using legacy virtio
Date: Mon, 31 Mar 2014 16:50:55 +0200 [thread overview]
Message-ID: <533980CF.4020904@suse.de> (raw)
In-Reply-To: <20140328105717.21018.17649.stgit@bahia.local>
On 03/28/2014 11:57 AM, Greg Kurz wrote:
> From: Rusty Russell <rusty@rustcorp.com.au>
>
> virtio data structures are defined as "target endian", which assumes
> that's a fixed value. In fact, that actually means it's platform-specific.
> The OASIS virtio 1.0 spec will fix this, by making all little endian.
>
> We need to support both implementations and we want to share as much code
> as possible.
>
> A good way to do it is to introduce a per-device boolean property to tell
> memory accessors whether they should swap bytes or not. This flag should
> be set at device reset time, because:
> - endianness won't change while the device is in use, and if we reboot
> into a different endianness, a new device reset will occur
> - as suggested by Alexander Graf, we can keep all the logic to set the
> property in a single place and share all the virtio memory accessors
> between the two implementations
>
> For legacy devices, we rely on a per-platform hook to set the flag. The
> virtio 1.0 implementation will just have to add some more logic in
> virtio_reset() instead of calling the hook:
>
> if (vdev->legacy) {
> vdev->needs_byteswap = virtio_legacy_get_byteswap();
> } else {
> #ifdef HOST_WORDS_BIGENDIAN
> vdev->needs_byteswap = true;
> #else
> vdev->needs_byteswap = false;
> #endif
> }
>
> The needs_byteswap flag is preserved accross migrations.
>
> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
> [ fixed checkpatch.pl error with the virtio_byteswap initialisation,
> ldq_phys() API change,
> relicensed virtio-access.h to GPLv2+ on Rusty's request,
> introduce a per-device needs_byteswap flag,
> add VirtIODevice * arg to virtio helpers,
> rename virtio_get_byteswap to virtio_legacy_get_byteswap,
> Greg Kurz <gkurz@linux.vnet.ibm.com> ]
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> hw/virtio/virtio.c | 5 +
> include/hw/virtio/virtio-access.h | 139 +++++++++++++++++++++++++++++++++++++
> include/hw/virtio/virtio.h | 3 +
> stubs/Makefile.objs | 1
> stubs/virtio_get_byteswap.c | 6 ++
> 5 files changed, 154 insertions(+)
> create mode 100644 include/hw/virtio/virtio-access.h
> create mode 100644 stubs/virtio_get_byteswap.c
>
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index aeabf3a..24b565f 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -19,6 +19,7 @@
> #include "hw/virtio/virtio.h"
> #include "qemu/atomic.h"
> #include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/virtio-access.h"
>
> /*
> * The alignment to use between consumer and producer parts of vring.
> @@ -546,6 +547,8 @@ void virtio_reset(void *opaque)
>
> virtio_set_status(vdev, 0);
>
> + vdev->needs_byteswap = virtio_legacy_get_byteswap();
> +
> if (k->reset) {
> k->reset(vdev);
> }
> @@ -845,6 +848,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
>
> qemu_put_8s(f, &vdev->status);
> qemu_put_8s(f, &vdev->isr);
> + qemu_put_8s(f, (uint8_t *) &vdev->needs_byteswap);
> qemu_put_be16s(f, &vdev->queue_sel);
> qemu_put_be32s(f, &vdev->guest_features);
> qemu_put_be32(f, vdev->config_len);
> @@ -905,6 +909,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
>
> qemu_get_8s(f, &vdev->status);
> qemu_get_8s(f, &vdev->isr);
> + qemu_get_8s(f, (uint8_t *) &vdev->needs_byteswap);
> qemu_get_be16s(f, &vdev->queue_sel);
> qemu_get_be32s(f, &features);
>
> diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> new file mode 100644
> index 0000000..70dd1e2
> --- /dev/null
> +++ b/include/hw/virtio/virtio-access.h
> @@ -0,0 +1,139 @@
> +/*
> + * Virtio Accessor Support: In case your target can change endian.
> + *
> + * Copyright IBM, Corp. 2013
> + *
> + * Authors:
> + * Rusty Russell <rusty@au.ibm.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + */
> +#ifndef _QEMU_VIRTIO_ACCESS_H
> +#define _QEMU_VIRTIO_ACCESS_H
> +#include "hw/virtio/virtio.h"
> +
> +static inline uint16_t virtio_lduw_phys(AddressSpace *as, hwaddr pa,
> + struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + return bswap16(lduw_phys(as, pa));
> + }
> + return lduw_phys(as, pa);
> +}
> +
> +static inline uint32_t virtio_ldl_phys(AddressSpace *as, hwaddr pa,
> + struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + return bswap32(ldl_phys(as, pa));
> + }
> + return ldl_phys(as, pa);
> +}
> +
> +static inline uint64_t virtio_ldq_phys(AddressSpace *as, hwaddr pa,
> + struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + return bswap64(ldq_phys(as, pa));
> + }
> + return ldq_phys(as, pa);
> +}
> +
> +static inline void virtio_stw_phys(AddressSpace *as, hwaddr pa, uint16_t value,
> + struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + stw_phys(as, pa, bswap16(value));
> + } else {
> + stw_phys(as, pa, value);
> + }
> +}
> +
> +static inline void virtio_stl_phys(AddressSpace *as, hwaddr pa, uint32_t value,
> + struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + stl_phys(as, pa, bswap32(value));
> + } else {
> + stl_phys(as, pa, value);
> + }
> +}
> +
> +static inline void virtio_stw_p(void *ptr, uint16_t v,
> + struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + stw_p(ptr, bswap16(v));
> + } else {
> + stw_p(ptr, v);
> + }
> +}
> +
> +static inline void virtio_stl_p(void *ptr, uint32_t v,
> + struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + stl_p(ptr, bswap32(v));
> + } else {
> + stl_p(ptr, v);
> + }
> +}
> +
> +static inline void virtio_stq_p(void *ptr, uint64_t v,
> + struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + stq_p(ptr, bswap64(v));
> + } else {
> + stq_p(ptr, v);
> + }
> +}
> +
> +static inline int virtio_lduw_p(const void *ptr, struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + return bswap16(lduw_p(ptr));
> + } else {
> + return lduw_p(ptr);
> + }
> +}
> +
> +static inline int virtio_ldl_p(const void *ptr, struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + return bswap32(ldl_p(ptr));
> + } else {
> + return ldl_p(ptr);
> + }
> +}
> +
> +static inline uint64_t virtio_ldq_p(const void *ptr, struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + return bswap64(ldq_p(ptr));
> + } else {
> + return ldq_p(ptr);
> + }
> +}
> +
> +static inline uint32_t virtio_tswap32(uint32_t s, struct VirtIODevice *vdev)
> +{
> + if (vdev->needs_byteswap) {
> + return bswap32(tswap32(s));
> + } else {
> + return tswap32(s);
> + }
> +}
> +
> +static inline void virtio_tswap32s(uint32_t *s, struct VirtIODevice *vdev)
> +{
> + tswap32s(s);
> + if (vdev->needs_byteswap) {
> + *s = bswap32(*s);
> + }
Couldn't you just reuse virtio_tswap32() here?
Also, I think a "needs_byteswap" flag gets confusing. Devices shouldn't
have any access to CPU endian specific RAM accessors.
How about we introduce a flag like "is_bigendian" that we set depending
on the CPU default endianness for legacy virtio. We can then change that
flag accordingly. For the wrappers here, we could just use accessors
like ldl_be_phys() or ldl_le_phys().
That should make things a lot easier to understand - and for virtio 1.0
we only need to set is_bigendian = false :).
Alex
next prev parent reply other threads:[~2014-03-31 14:51 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-28 10:57 [Qemu-devel] [PATCH v6 0/8] virtio endian-ambivalent target fixes Greg Kurz
2014-03-28 10:57 ` [Qemu-devel] [PATCH v6 1/8] virtio_legacy_get_byteswap: endian-ambivalent targets using legacy virtio Greg Kurz
2014-03-28 14:15 ` Thomas Huth
2014-03-28 15:40 ` Greg Kurz
2014-03-28 17:59 ` Andreas Färber
2014-03-28 19:00 ` Greg Kurz
2014-03-31 14:50 ` Alexander Graf [this message]
2014-04-01 11:54 ` Greg Kurz
2014-03-28 10:57 ` [Qemu-devel] [PATCH v6 2/8] virtio: allow byte swapping for vring and config access Greg Kurz
2014-03-28 16:07 ` Thomas Huth
2014-03-28 17:02 ` Greg Kurz
2014-03-31 16:24 ` Alexander Graf
2014-03-31 16:26 ` Andreas Färber
2014-04-01 12:03 ` Greg Kurz
2014-03-28 10:57 ` [Qemu-devel] [PATCH v6 3/8] virtio-net: use virtio wrappers to access headers Greg Kurz
2014-03-31 16:28 ` Alexander Graf
2014-03-28 10:57 ` [Qemu-devel] [PATCH v6 4/8] virtio-balloon: use virtio wrappers to access page frame numbers Greg Kurz
2014-03-31 16:30 ` Alexander Graf
2014-03-28 10:57 ` [Qemu-devel] [PATCH v6 5/8] virtio-blk: use virtio wrappers to access headers Greg Kurz
2014-03-31 16:31 ` Alexander Graf
2014-03-28 10:57 ` [Qemu-devel] [PATCH v6 6/8] virtio-scsi: " Greg Kurz
2014-03-28 17:13 ` Greg Kurz
2014-03-28 17:21 ` Andreas Färber
2014-03-28 17:37 ` Greg Kurz
2014-03-28 17:43 ` Peter Maydell
2014-03-28 18:04 ` Greg Kurz
2014-03-28 18:14 ` Peter Maydell
2014-03-28 18:58 ` Greg Kurz
2014-03-31 16:34 ` Alexander Graf
2014-03-28 10:58 ` [Qemu-devel] [PATCH v6 7/8] virtio-serial-bus: " Greg Kurz
2014-03-31 17:01 ` Alexander Graf
2014-03-28 10:58 ` [Qemu-devel] [PATCH v6 8/8] virtio-9p: " Greg Kurz
2014-03-28 11:22 ` [Qemu-devel] [PATCH v4] target-ppc: ppc64 target's virtio can be either endian Greg Kurz
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=533980CF.4020904@suse.de \
--to=agraf@suse.de \
--cc=afaerber@suse.de \
--cc=anthony@codemonkey.ws \
--cc=cornelia.huck@de.ibm.com \
--cc=gkurz@linux.vnet.ibm.com \
--cc=kwolf@redhat.com \
--cc=marc.zyngier@arm.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rusty@rustcorp.com.au \
--cc=stefanha@redhat.com \
--cc=thuth@linux.vnet.ibm.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.