Skip to content

Commit

Permalink
virtio: Fix virtio_mmio_read()/virtio_mmio_write()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
vivier authored and mstsirkin committed Mar 22, 2021
1 parent f0f2002 commit 0ab8c02
Showing 1 changed file with 52 additions and 22 deletions.
74 changes: 52 additions & 22 deletions hw/virtio/virtio-mmio.c
Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 0ab8c02

Please sign in to comment.