From 395b6a18728feca247bad3adea3b7c6884eb30fd Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Fri, 17 Jan 2014 19:15:23 -0500 Subject: [PATCH 1/6] init_virtio_scsi(): reset the HBA before freeing its virtio ring Message-id: <1389986123-16290-1-git-send-email-lersek@redhat.com> Patchwork-id: 56797 O-Subject: [RHEL-7.0 seabios PATCH] init_virtio_scsi(): reset the HBA before freeing its virtio ring Bugzilla: 1013418 RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Kevin Wolf RH-Acked-by: Paolo Bonzini Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1013418 Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=6893168 When init_virtio_scsi() finds no SCSI targets connected to the HBA, it frees the virtio ring. Other code in SeaBIOS proceeds to overwrite the area. However, the ring is in use by qemu at that point -- not only did we report the (ACK|DRIVER|DRIVER_OK) status earlier, we even communicated over the ring. Of course SeaBIOS doesn't "kick" the HBA ever again, hence qemu has no reason to look at the ring. However, when qemu uses KVM acceleration, and ioeventfd is enabled for the HBA, then a vmstate change to "running" (including stop->cont monitor commands and incoming migration) "forces" a kick (see qemu commit 25db9ebe). Qemu then tries to interpret whatever unrelated guest data is in the HBA's original ring area, as virtio protocol. Qemu exits upon seeing the garbage. init_virtio_scsi() should reset the HBA before allowing the virtio ring memory to be reused. Device reset causes the hypervisor to drop its references. This change is justified / underpinned by pure virtio-spec compliance as well. Related RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1013418 Signed-off-by: Laszlo Ersek (cherry picked from commit 5f2d17d35b2339526f3b3d580b279ea78e406a25) --- src/virtio-scsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) Signed-off-by: Miroslav Rezanina --- src/virtio-scsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/virtio-scsi.c b/src/virtio-scsi.c index bf6c68b..7caf405 100644 --- a/src/virtio-scsi.c +++ b/src/virtio-scsi.c @@ -154,8 +154,10 @@ init_virtio_scsi(struct pci_device *pci) for (tot = 0, i = 0; i < 256; i++) tot += virtio_scsi_scan_target(pci, ioaddr, vq, i); - if (!tot) + if (!tot) { + vp_reset(ioaddr); goto fail; + } return; -- 1.8.3.1