qemu/include/hw/virtio/dataplane/vring-accessors.h
Cornelia Huck b0e5d90ebc dataplane: endianness-aware accesses
The vring.c code currently assumes that guest and host endianness match,
which is not true for a number of cases:

- emulating targets with a different endianness than the host
- bi-endian targets, where the correct endianness depends on the virtio
  device
- upcoming support for the virtio-1 standard mandates little-endian
  accesses even for big-endian targets and hosts

Make sure to use accessors that depend on the virtio device.

Note that dataplane now needs to be built per-target.

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Fam Zheng <famz@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Tested-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1422289602-17874-2-git-send-email-cornelia.huck@de.ibm.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-02-16 15:07:16 +00:00

76 lines
2.1 KiB
C

#ifndef VRING_ACCESSORS_H
#define VRING_ACCESSORS_H
#include "hw/virtio/virtio_ring.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-access.h"
static inline uint16_t vring_get_used_idx(VirtIODevice *vdev, Vring *vring)
{
return virtio_tswap16(vdev, vring->vr.used->idx);
}
static inline void vring_set_used_idx(VirtIODevice *vdev, Vring *vring,
uint16_t idx)
{
vring->vr.used->idx = virtio_tswap16(vdev, idx);
}
static inline uint16_t vring_get_avail_idx(VirtIODevice *vdev, Vring *vring)
{
return virtio_tswap16(vdev, vring->vr.avail->idx);
}
static inline uint16_t vring_get_avail_ring(VirtIODevice *vdev, Vring *vring,
int i)
{
return virtio_tswap16(vdev, vring->vr.avail->ring[i]);
}
static inline void vring_set_used_ring_id(VirtIODevice *vdev, Vring *vring,
int i, uint32_t id)
{
vring->vr.used->ring[i].id = virtio_tswap32(vdev, id);
}
static inline void vring_set_used_ring_len(VirtIODevice *vdev, Vring *vring,
int i, uint32_t len)
{
vring->vr.used->ring[i].len = virtio_tswap32(vdev, len);
}
static inline uint16_t vring_get_used_flags(VirtIODevice *vdev, Vring *vring)
{
return virtio_tswap16(vdev, vring->vr.used->flags);
}
static inline uint16_t vring_get_avail_flags(VirtIODevice *vdev, Vring *vring)
{
return virtio_tswap16(vdev, vring->vr.avail->flags);
}
static inline void vring_set_used_flags(VirtIODevice *vdev, Vring *vring,
uint16_t flags)
{
vring->vr.used->flags |= virtio_tswap16(vdev, flags);
}
static inline void vring_clear_used_flags(VirtIODevice *vdev, Vring *vring,
uint16_t flags)
{
vring->vr.used->flags &= virtio_tswap16(vdev, ~flags);
}
static inline unsigned int vring_get_num(Vring *vring)
{
return vring->vr.num;
}
/* Are there more descriptors available? */
static inline bool vring_more_avail(VirtIODevice *vdev, Vring *vring)
{
return vring_get_avail_idx(vdev, vring) != vring->last_avail_idx;
}
#endif