From patchwork Fri Sep 4 08:54:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 514353 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 77CDC1401DE for ; Fri, 4 Sep 2015 18:55:27 +1000 (AEST) Received: from localhost ([::1]:57141 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZXmmL-0007d0-Lv for incoming@patchwork.ozlabs.org; Fri, 04 Sep 2015 04:55:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44887) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZXmld-0006JN-07 for qemu-devel@nongnu.org; Fri, 04 Sep 2015 04:54:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZXmlZ-0002m2-Ig for qemu-devel@nongnu.org; Fri, 04 Sep 2015 04:54:40 -0400 Received: from e06smtp09.uk.ibm.com ([195.75.94.105]:56685) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZXmlZ-0002kv-AS for qemu-devel@nongnu.org; Fri, 04 Sep 2015 04:54:37 -0400 Received: from /spool/local by e06smtp09.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 4 Sep 2015 09:54:35 +0100 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp09.uk.ibm.com (192.168.101.139) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 4 Sep 2015 09:54:34 +0100 X-Helo: d06dlp03.portsmouth.uk.ibm.com X-MailFrom: cornelia.huck@de.ibm.com X-RcptTo: qemu-devel@nongnu.org Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id 7A53F1B0805F for ; Fri, 4 Sep 2015 09:56:09 +0100 (BST) Received: from d06av12.portsmouth.uk.ibm.com (d06av12.portsmouth.uk.ibm.com [9.149.37.247]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t848sXra40501340 for ; Fri, 4 Sep 2015 08:54:33 GMT Received: from d06av12.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av12.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t848sW0Y006377 for ; Fri, 4 Sep 2015 02:54:33 -0600 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av12.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t848sVKu006342 (version=TLSv1/SSLv3 cipher=AES256-SHA256 bits=256 verify=NO); Fri, 4 Sep 2015 02:54:32 -0600 From: Cornelia Huck To: qemu-devel@nongnu.org Date: Fri, 4 Sep 2015 10:54:26 +0200 Message-Id: <1441356869-57861-2-git-send-email-cornelia.huck@de.ibm.com> X-Mailer: git-send-email 2.3.8 In-Reply-To: <1441356869-57861-1-git-send-email-cornelia.huck@de.ibm.com> References: <1441356869-57861-1-git-send-email-cornelia.huck@de.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15090408-0037-0000-0000-000003C8AC96 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.75.94.105 Cc: Cornelia Huck , borntraeger@de.ibm.com, jasowang@redhat.com, mst@redhat.com Subject: [Qemu-devel] [PATCH 1/4] virtio: ring sizes vs. reset X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org We allow guests to change the size of the virtqueue rings by supplying a number of buffers that is different from the number of buffers the device was initialized with. Current code has some problems, however, since reset does not reset the ringsizes to the default values (as this is not saved anywhere). Let's extend the core code to keep track of the default ringsizes and migrate them once the guest changed them for any of the virtqueues for a device. Signed-off-by: Cornelia Huck --- hw/virtio/virtio.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ include/hw/virtio/virtio.h | 1 + 2 files changed, 64 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 788b556..687116e 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -60,6 +60,7 @@ typedef struct VRingUsed typedef struct VRing { unsigned int num; + unsigned int num_default; unsigned int align; hwaddr desc; hwaddr avail; @@ -633,7 +634,9 @@ void virtio_reset(void *opaque) vdev->vq[i].signalled_used = 0; vdev->vq[i].signalled_used_valid = false; vdev->vq[i].notification = true; + vdev->vq[i].vring.num = vdev->vq[i].vring.num_default; } + vdev->non_default_ringsizes = false; } uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr) @@ -855,6 +858,10 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num) return; } vdev->vq[n].vring.num = num; + if (num != vdev->vq[n].vring.num_default) { + /* save ringsizes once one of them has been changed */ + vdev->non_default_ringsizes = true; + } } VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector) @@ -964,6 +971,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, abort(); vdev->vq[i].vring.num = queue_size; + vdev->vq[i].vring.num_default = queue_size; vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN; vdev->vq[i].handle_output = handle_output; @@ -977,6 +985,7 @@ void virtio_del_queue(VirtIODevice *vdev, int n) } vdev->vq[n].vring.num = 0; + vdev->vq[n].vring.num_default = 0; } void virtio_irq(VirtQueue *vq) @@ -1056,6 +1065,13 @@ static bool virtio_virtqueue_needed(void *opaque) return virtio_host_has_feature(vdev, VIRTIO_F_VERSION_1); } +static bool virtio_ringsize_needed(void *opaque) +{ + VirtIODevice *vdev = opaque; + + return vdev->non_default_ringsizes; +} + static void put_virtqueue_state(QEMUFile *f, void *pv, size_t size) { VirtIODevice *vdev = pv; @@ -1104,6 +1120,52 @@ static const VMStateDescription vmstate_virtio_virtqueues = { } }; +static void put_ringsize_state(QEMUFile *f, void *pv, size_t size) +{ + VirtIODevice *vdev = pv; + int i; + + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { + qemu_put_be32(f, vdev->vq[i].vring.num_default); + } +} + +static int get_ringsize_state(QEMUFile *f, void *pv, size_t size) +{ + VirtIODevice *vdev = pv; + int i; + + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { + vdev->vq[i].vring.num_default = qemu_get_be32(f); + } + return 0; +} + +static VMStateInfo vmstate_info_ringsize = { + .name = "ringsize_state", + .get = get_ringsize_state, + .put = put_ringsize_state, +}; + +static const VMStateDescription vmstate_virtio_ringsize = { + .name = "virtio/ringsize", + .version_id = 1, + .minimum_version_id = 1, + .needed = &virtio_ringsize_needed, + .fields = (VMStateField[]) { + { + .name = "ringsize", + .version_id = 0, + .field_exists = NULL, + .size = 0, + .info = &vmstate_info_ringsize, + .flags = VMS_SINGLE, + .offset = 0, + }, + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_virtio_device_endian = { .name = "virtio/device_endian", .version_id = 1, @@ -1138,6 +1200,7 @@ static const VMStateDescription vmstate_virtio = { &vmstate_virtio_device_endian, &vmstate_virtio_64bit_features, &vmstate_virtio_virtqueues, + &vmstate_virtio_ringsize, NULL } }; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index cccae89..29870c8 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -90,6 +90,7 @@ struct VirtIODevice VMChangeStateEntry *vmstate; char *bus_name; uint8_t device_endian; + bool non_default_ringsizes; QLIST_HEAD(, VirtQueue) *vector_queues; };