I'm a bit confused. So right now, the higher level virtio functions do
endianness conversion. I really want to make sure that if a guest tries
to read a 4-byte PCI config field, that it does so using an "outl"
instruction so that in my QEMU backend, I don't have to deal with a
guest reading/writing a single byte within a 4-byte configuration
field. It's the difference between having in the PIO handler:
switch (addr) {
case VIRTIO_BLK_CONFIG_MAX_SEG:
return vdev->max_seg;
case VIRTIO_BLK_CONFIG_MAX_SIZE:
return vdev->max_size;
....
}
and:
switch (addr) {
case VIRTIO_BLK_CONFIG_MAX_SEG:
return vdev->max_seg & 0xFF;
case VIRTIO_BLK_CONFIG_MAX_SEG + 1:
return (vdev->max_seg >> 8) & 0xFF;
case VIRTIO_BLK_CONFIG_MAX_SEG + 2:
return (vdev->max_seg >> 16) & 0xFF;
case VIRTIO_BLK_CONFIG_MAX_SEG + 3:
return (vdev->max_seg >> 24) & 0xFF;
case VIRTIO_BLK_CONFIG_MAX_SIZE:
return vdev->max_size & 0xFF;
case VIRTIO_BLK_CONFIG_MAX_SIZE + 1:
return (vdev->max_size >> 8) & 0xFF;
case VIRTIO_BLK_CONFIG_MAX_SIZE + 2:
return (vdev->max_size >> 16) & 0xFF;
case VIRTIO_BLK_CONFIG_MAX_SIZE + 3:
return (vdev->max_size >> 24) & 0xFF;
...
}
It's the host-side code I'm concerned about, not the guest-side code.
I'm happy to just ignore the whole endianness conversion thing and
always pass values through in the CPU bitness but it's very important to
me that the PCI config registers are accessed with their natural sized
instructions (just as they would with a real PCI device).
Regards,
Anthony Liguori
-