From nobody Mon Feb 9 07:22:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1488435958763832.22110769498; Wed, 1 Mar 2017 22:25:58 -0800 (PST) Received: from localhost ([::1]:50626 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cjKBZ-0005Rs-GY for importer@patchew.org; Thu, 02 Mar 2017 01:25:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44405) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cjK6e-0001le-9K for qemu-devel@nongnu.org; Thu, 02 Mar 2017 01:20:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cjK6d-00045b-4Z for qemu-devel@nongnu.org; Thu, 02 Mar 2017 01:20:52 -0500 Received: from mail.kernel.org ([198.145.29.136]:51326) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cjK6c-00043W-RS for qemu-devel@nongnu.org; Thu, 02 Mar 2017 01:20:51 -0500 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 005C520320; Thu, 2 Mar 2017 06:20:49 +0000 (UTC) Received: from redhat.com (pool-96-237-235-121.bstnma.fios.verizon.net [96.237.235.121]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 518C3202E5; Thu, 2 Mar 2017 06:20:47 +0000 (UTC) Date: Thu, 2 Mar 2017 08:20:46 +0200 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Message-ID: <1488435591-17882-12-git-send-email-mst@redhat.com> References: <1488435591-17882-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1488435591-17882-1-git-send-email-mst@redhat.com> X-Mailer: git-send-email 2.8.0.287.g0deeb61 X-Mutt-Fcc: =sent X-Virus-Scanned: ClamAV using ClamSMTP X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 198.145.29.136 Subject: [Qemu-devel] [PULL 11/15] virtio: add missing region cache init in virtio_load() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , "Dr . David Alan Gilbert" , Eric Auger , Stefan Hajnoczi , Cornelia Huck , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Stefan Hajnoczi Commit 97cd965c070152bc626c7507df9fb356bbe1cd81 ("virtio: use VRingMemoryRegionCaches for avail and used rings") switched to a memory region cache to avoid repeated map/unmap operations. The virtio_load() process is a little tricky because vring addresses are serialized in two separate places. VIRTIO 1.0 devices serialize desc and then a subsection with used and avail. Legacy devices only serialize desc. Live migration of VIRTIO 1.0 devices fails on the destination host with: VQ 0 size 0x80 < last_avail_idx 0x12f8 - used_idx 0x0 Failed to load virtio-blk:virtio error while loading state for instance 0x0 of device '0000:00:04.0/virtio= -blk' This happens because the memory region cache is only initialized after desc is loaded and not after the used and avail subsection is loaded. If the guest chose memory addresses that don't match the legacy ring layout then the wrong guest memory location is accessed. Wait until all ring addresses are known before trying to initialize the region cache. Also clarify the incomplete comment about VIRTIO-1 ring address subsection. Cc: Dr. David Alan Gilbert Cc: Paolo Bonzini Signed-off-by: Stefan Hajnoczi Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck Tested-by: Eric Auger --- hw/virtio/virtio.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 294c909..efce4b3 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1857,7 +1857,10 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) if (k->has_variable_vring_alignment) { qemu_put_be32(f, vdev->vq[i].vring.align); } - /* XXX virtio-1 devices */ + /* + * Save desc now, the rest of the ring addresses are saved in + * subsections for VIRTIO-1 devices. + */ qemu_put_be64(f, vdev->vq[i].vring.desc); qemu_put_be16s(f, &vdev->vq[i].last_avail_idx); if (k->save_queue) { @@ -1998,14 +2001,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, in= t version_id) vdev->vq[i].signalled_used_valid =3D false; vdev->vq[i].notification =3D true; =20 - if (vdev->vq[i].vring.desc) { - /* XXX virtio-1 devices */ - virtio_queue_update_rings(vdev, i); - } else if (vdev->vq[i].last_avail_idx) { + if (!vdev->vq[i].vring.desc && vdev->vq[i].last_avail_idx) { error_report("VQ %d address 0x0 " "inconsistent with Host index 0x%x", i, vdev->vq[i].last_avail_idx); - return -1; + return -1; } if (k->load_queue) { ret =3D k->load_queue(qbus->parent, i, f); @@ -2066,6 +2066,19 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int= version_id) for (i =3D 0; i < num; i++) { if (vdev->vq[i].vring.desc) { uint16_t nheads; + + /* + * VIRTIO-1 devices migrate desc, used, and avail ring address= es so + * only the region cache needs to be set up. Legacy devices n= eed + * to calculate used and avail ring addresses based on the desc + * address. + */ + if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) { + virtio_init_region_cache(vdev, i); + } else { + virtio_queue_update_rings(vdev, i); + } + nheads =3D vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_av= ail_idx; /* Check it isn't doing strange things with descriptor numbers= . */ if (nheads > vdev->vq[i].vring.num) { --=20 MST