virtio: Fix virtio_mmio_read()/virtio_mmio_write()
Both functions don't check the personality of the interface (legacy or modern) before accessing the configuration memory and always use virtio_config_readX()/virtio_config_writeX(). With this patch, they now check the personality and in legacy mode call virtio_config_readX()/virtio_config_writeX(), otherwise call virtio_config_modern_readX()/virtio_config_modern_writeX(). This change has been tested with virtio-mmio guests (virt stretch/armhf and virt sid/m68k) and virtio-pci guests (pseries RHEL-7.3/ppc64 and /ppc64le). Signed-off-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210314200300.3259170-1-laurent@vivier.eu> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
f0f20022a0
commit
0ab8c021c6
@ -112,15 +112,28 @@ static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
|
||||
|
||||
if (offset >= VIRTIO_MMIO_CONFIG) {
|
||||
offset -= VIRTIO_MMIO_CONFIG;
|
||||
switch (size) {
|
||||
case 1:
|
||||
return virtio_config_readb(vdev, offset);
|
||||
case 2:
|
||||
return virtio_config_readw(vdev, offset);
|
||||
case 4:
|
||||
return virtio_config_readl(vdev, offset);
|
||||
default:
|
||||
abort();
|
||||
if (proxy->legacy) {
|
||||
switch (size) {
|
||||
case 1:
|
||||
return virtio_config_readb(vdev, offset);
|
||||
case 2:
|
||||
return virtio_config_readw(vdev, offset);
|
||||
case 4:
|
||||
return virtio_config_readl(vdev, offset);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
switch (size) {
|
||||
case 1:
|
||||
return virtio_config_modern_readb(vdev, offset);
|
||||
case 2:
|
||||
return virtio_config_modern_readw(vdev, offset);
|
||||
case 4:
|
||||
return virtio_config_modern_readl(vdev, offset);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (size != 4) {
|
||||
@ -245,20 +258,37 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
|
||||
if (offset >= VIRTIO_MMIO_CONFIG) {
|
||||
offset -= VIRTIO_MMIO_CONFIG;
|
||||
switch (size) {
|
||||
case 1:
|
||||
virtio_config_writeb(vdev, offset, value);
|
||||
break;
|
||||
case 2:
|
||||
virtio_config_writew(vdev, offset, value);
|
||||
break;
|
||||
case 4:
|
||||
virtio_config_writel(vdev, offset, value);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
if (proxy->legacy) {
|
||||
switch (size) {
|
||||
case 1:
|
||||
virtio_config_writeb(vdev, offset, value);
|
||||
break;
|
||||
case 2:
|
||||
virtio_config_writew(vdev, offset, value);
|
||||
break;
|
||||
case 4:
|
||||
virtio_config_writel(vdev, offset, value);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
switch (size) {
|
||||
case 1:
|
||||
virtio_config_modern_writeb(vdev, offset, value);
|
||||
break;
|
||||
case 2:
|
||||
virtio_config_modern_writew(vdev, offset, value);
|
||||
break;
|
||||
case 4:
|
||||
virtio_config_modern_writel(vdev, offset, value);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (size != 4) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
|
Loading…
Reference in New Issue
Block a user