Subject: [PATCH 0/3] virtio-mmio: handle BE guests on LE hosts

From: [email-masked] (Michael S. Tsirkin)
Date: Tue, 15 Oct 2013 09:38:31 +0300

On Tue, Oct 15, 2013 at 09:53:17AM +1030, Rusty Russell wrote:
> "Michael S. Tsirkin" <[email-masked]> writes:
> > On Mon, Oct 14, 2013 at 06:50:48PM +0200, Paolo Bonzini wrote:
> >> Il 14/10/2013 17:36, Marc Zyngier ha scritto:
> >> >> > 
> >> >> > Devices are fine in QEMU, it's only the "generic" parts (rings) that are
> >> >> > missing AFAICT.
> >> > So if I understand correctly how it works, target endianness is set at
> >> > compile time, and you have a BE specific QEMU?
> >> 
> >> Yes.  Though as Alex said, this will have to change for PPC
> >> little-endian support.
> >> 
> >> Paolo
> >
> > Or we'll just say that this platform requires virtio 1.0.
> 
> To come full circle, I have implemented virtio support for BE PPC in
> qemu :) And we'll be supporting pre-1.0 for the moment. I'm awaiting
> some ppc-specific hooks, but it could be merged without them.
> 
> It's icky: we don't really want to use the current endianness of the
> CPU, since in theory a BE kernel could be running an LE process.  So at
> the time of virtio device reset (the first thing the Linux drivers do)
> we read the endianness of the interrupt entry point, which is presumably
> the OS endianness.

Indeed, ick.
The next thing after reset is status write:

        /* We always start by resetting the device, in case a previous
         * driver messed it up.  This also tests that code path a
         * little. */
        dev->config->reset(dev);

        /* Acknowledge that we've seen the device. */
        add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);

and mmio happens to use a 32 bit register for this:

	static void vm_set_status(struct virtio_device *vdev, u8 status)
	{
		struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);

		/* We should never be setting status to 0. */
		BUG_ON(status == 0);

		writel(status, vm_dev->base + VIRTIO_MMIO_STATUS);
	}

so if we only care about mmio, we can use the status write
to detect endian-ness: low byte set means LE, high byte set
means BE, which seems cleaner.

Hmm?

-- 
MST