Message ID | 20210314200300.3259170-1-laurent@vivier.eu |
---|---|
State | New |
Headers | show |
Series | virtio: Fix virtio_mmio_read()/virtio_mmio_write() | expand |
Hi, could this fix be merged in QEMU 6.0? Thanks, Laurent Le 14/03/2021 à 21:03, Laurent Vivier a écrit : > 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> > --- > hw/virtio/virtio-mmio.c | 74 +++++++++++++++++++++++++++++------------ > 1 file changed, 52 insertions(+), 22 deletions(-) > > diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c > index 6990b9879cf0..342c918ea7b7 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, >
On Sun, Mar 14, 2021 at 09:03:00PM +0100, Laurent Vivier wrote: >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> >--- > hw/virtio/virtio-mmio.c | 74 +++++++++++++++++++++++++++++------------ > 1 file changed, 52 insertions(+), 22 deletions(-) > Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 6990b9879cf0..342c918ea7b7 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,
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> --- hw/virtio/virtio-mmio.c | 74 +++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 22 deletions(-)