On 28.05.2013, at 12:18, Michael S. Tsirkin wrote: > When a BE guest reads capacity from an LE host virtio-blk device or vice > versa, it will get the dwords of the qword field swapped. > As virtio-blk is the only one with such a quirk, > and as non-pci transports don't do byte-swaps at all, > solve this with a bit of device-specific hackery in > virtio-pci. > > Signed-off-by: Michael S. Tsirkin <m...@redhat.com> > --- > > Changes from v1: > fixed some obvious bugs. > > I don't seem to be able to boot any big-endian > guests ATM, so this is only compile-tested - sending
Huh? Why not? Qemu-system-ppc64 -M pseries -m 1G should be in good enough shape to boot your favorite Linux distro's installation DVD. > this out for early feedback/flames. > Testing reports also wellcome! While the hack looks like a hack, I can't really think of anything better either. Alex > > > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c > index 9668b2b..e7971cc 100644 > --- a/hw/virtio/virtio-pci.c > +++ b/hw/virtio/virtio-pci.c > @@ -98,6 +98,12 @@ > /* HACK for virtio to determine if it's running a big endian guest */ > bool virtio_is_big_endian(void); > > +#ifdef HOST_WORDS_BIGENDIAN > +#define VIRTIO_HOST_IS_BIG_ENDIAN true > +#else > +#define VIRTIO_HOST_IS_BIG_ENDIAN false > +#endif > + > static void virtio_pci_bus_new(VirtioBusState *bus, VirtIOPCIProxy *dev); > > /* virtio device */ > @@ -411,6 +417,15 @@ static uint64_t virtio_pci_config_read(void *opaque, > hwaddr addr, > } > break; > case 4: > + /* Most devices don't have 64 bit config fields. > + * Block is an exception: first 8 bytes include > + * a 64 bit capacity field. > + */ > + if (virtio_is_big_endian() != VIRTIO_HOST_IS_BIG_ENDIAN && > + proxy->vdev->device_id == VIRTIO_ID_BLOCK && addr < 8) { > + /* Swap first two words */ > + addr ^= 0x4; > + } > val = virtio_config_readl(proxy->vdev, addr); > if (virtio_is_big_endian()) { > val = bswap32(val);