summaryrefslogtreecommitdiffstats
path: root/include/hw
diff options
context:
space:
mode:
authorGreg Kurz2014-06-24 19:38:54 +0200
committerMichael S. Tsirkin2014-06-29 18:39:42 +0200
commit616a655219a92ae7cf5d6a7862e6489c6282009e (patch)
tree034610ea9da38e5895f4083c16c12dc1b45a63d7 /include/hw
parentcpu: introduce CPUClass::virtio_is_big_endian() (diff)
downloadqemu-616a655219a92ae7cf5d6a7862e6489c6282009e.tar.gz
qemu-616a655219a92ae7cf5d6a7862e6489c6282009e.tar.xz
qemu-616a655219a92ae7cf5d6a7862e6489c6282009e.zip
virtio: add endian-ambivalent support to VirtIODevice
Some CPU families can dynamically change their endianness. This means we can have little endian ppc or big endian arm guests for example. This has an impact on legacy virtio data structures since they are target endian. We hence introduce a new property to track the endianness of each virtio device. It is reasonnably assumed that endianness won't change while the device is in use : we hence capture the device endianness when it gets reset. We migrate this property in a subsection, after the device descriptor. This means the load code must not rely on it until it is restored. As a consequence, the vring sanity checks had to be moved after the call to vmstate_load_state(). We enforce paranoia by poisoning the property at the begining of virtio_load(). Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'include/hw')
-rw-r--r--include/hw/virtio/virtio.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 9000ee2f50..a60104ca24 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -104,6 +104,12 @@ typedef struct VirtQueueElement
#define VIRTIO_DEVICE(obj) \
OBJECT_CHECK(VirtIODevice, (obj), TYPE_VIRTIO_DEVICE)
+enum virtio_device_endian {
+ VIRTIO_DEVICE_ENDIAN_UNKNOWN,
+ VIRTIO_DEVICE_ENDIAN_LITTLE,
+ VIRTIO_DEVICE_ENDIAN_BIG,
+};
+
struct VirtIODevice
{
DeviceState parent_obj;
@@ -121,6 +127,7 @@ struct VirtIODevice
bool vm_running;
VMChangeStateEntry *vmstate;
char *bus_name;
+ uint8_t device_endian;
};
typedef struct VirtioDeviceClass {
@@ -256,9 +263,9 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
void virtio_queue_notify_vq(VirtQueue *vq);
void virtio_irq(VirtQueue *vq);
-bool target_words_bigendian(void);
-static inline bool virtio_is_big_endian(void)
+static inline bool virtio_is_big_endian(VirtIODevice *vdev)
{
- return target_words_bigendian();
+ assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
+ return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
}
#endif