diff options
author | Laurent Vivier <laurent@vivier.eu> | 2021-03-14 21:03:00 +0100 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2021-03-22 10:17:53 -0400 |
commit | 0ab8c021c6c594846915cbeb501fa87ab8780949 (patch) | |
tree | 00abf519ed1f5c165ab66ac102139c2a557e9284 /hw/virtio | |
parent | f0f20022a0c744930935fdb7020a8c18347d391a (diff) | |
download | qemu-0ab8c021c6c594846915cbeb501fa87ab8780949.zip qemu-0ab8c021c6c594846915cbeb501fa87ab8780949.tar.gz qemu-0ab8c021c6c594846915cbeb501fa87ab8780949.tar.bz2 |
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>
Diffstat (limited to 'hw/virtio')
-rw-r--r-- | hw/virtio/virtio-mmio.c | 74 |
1 files changed, 52 insertions, 22 deletions
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 6990b98..342c918 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -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, |