Message ID | 20180702063725.8087-1-pagupta@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Jul 02, 2018 at 12:07:25PM +0530, Pankaj Gupta wrote: > virtio-rng device causing old guest kernels(2.6.32) to hang on latest qemu. > The driver attempts to read from the virtio-rng device too early in it's > initialization. Qemu detects guest is not ready and returns, resulting in > hang. > > Fix is to handle pending request when guest is running and driver status is > set to 'VIRTIO_CONFIG_S_DRIVER_OK'. > > Reported-by: Sergio lopez <slopezpa@redhat.com> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> > Signed-off-by: Pankaj Gupta <pagupta@redhat.com> > --- > v3->v4: Added signed-off & reported-by tags again. > v2->v3: Add comment to explain virtio-rng early status update (Stefan) > v1->v2: Update new status value early only for virtio-rng (Stefan) > > hw/virtio/virtio-rng.c | 19 +++++++++++++++++++ > 1 file changed, 19 insertions(+) > > diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c > index 289bbcac03..0b586bd750 100644 > --- a/hw/virtio/virtio-rng.c > +++ b/hw/virtio/virtio-rng.c > @@ -156,6 +156,24 @@ static void check_rate_limit(void *opaque) > vrng->activate_timer = true; > } > > +static void virtio_rng_set_status(VirtIODevice *vdev, uint8_t status) > +{ > + VirtIORNG *vrng = VIRTIO_RNG(vdev); > + > + if (!vdev->vm_running) { > + return; > + } > + /* Set device status in VirtIODevice object. Its used in 'is_guest_ready' s/Its/It's/ Can be fixed when merging. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index 289bbcac03..0b586bd750 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -156,6 +156,24 @@ static void check_rate_limit(void *opaque) vrng->activate_timer = true; } +static void virtio_rng_set_status(VirtIODevice *vdev, uint8_t status) +{ + VirtIORNG *vrng = VIRTIO_RNG(vdev); + + if (!vdev->vm_running) { + return; + } + /* Set device status in VirtIODevice object. Its used in 'is_guest_ready' + * function to check if guest is ready and process the pending requests. + * Other virtio devices might be dependent on old value of status, so + * update status early only for virtio-rng. + */ + vdev->status = status; + + /* Something changed, try to process buffers */ + virtio_rng_process(vrng); +} + static void virtio_rng_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); @@ -261,6 +279,7 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data) vdc->realize = virtio_rng_device_realize; vdc->unrealize = virtio_rng_device_unrealize; vdc->get_features = get_features; + vdc->set_status = virtio_rng_set_status; } static const TypeInfo virtio_rng_info = {