From patchwork Mon May 25 13:34:05 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 25839 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n4PDbumA012394 for ; Mon, 25 May 2009 13:37:56 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751645AbZEYNhw (ORCPT ); Mon, 25 May 2009 09:37:52 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751540AbZEYNhw (ORCPT ); Mon, 25 May 2009 09:37:52 -0400 Received: from mx2.redhat.com ([66.187.237.31]:40633 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751495AbZEYNhv (ORCPT ); Mon, 25 May 2009 09:37:51 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n4PDZ5HN010348; Mon, 25 May 2009 09:35:05 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n4PDZ4rN011490; Mon, 25 May 2009 09:35:04 -0400 Received: from redhat.com (vpn-10-169.str.redhat.com [10.32.10.169]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n4PDZ0Dx030674; Mon, 25 May 2009 09:35:01 -0400 Date: Mon, 25 May 2009 16:34:05 +0300 From: "Michael S. Tsirkin" To: Paul Brook , Avi Kivity , qemu-devel@nongnu.org, Carsten Otte , kvm@vger.kernel.org, Rusty Russell , virtualization@lists.linux-foundation.org, Christian Borntraeger , Blue Swirl , Anthony Liguori Subject: [PATCH] qemu: virtio save/load bindings Message-ID: <20090525133405.GA6166@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) X-Scanned-By: MIMEDefang 2.58 on 172.16.27.26 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Implement bindings for virtio save/load. Use them in virtio pci. Signed-off-by: Michael S. Tsirkin --- Is anyone working to fill in load/save bindings so that saving virtio devices works? Here's a trivial patch to do this (this one is on top of my MSI-X patchset). Comments? hw/virtio-pci.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- hw/virtio.c | 31 ++++++++++++++----------------- hw/virtio.h | 4 ++++ 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 294f4c7..589fbb1 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -105,6 +105,48 @@ static void virtio_pci_notify(void *opaque, uint16_t vector) qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); } +static void virtio_pci_save_config(void * opaque, QEMUFile *f) +{ + VirtIOPCIProxy *proxy = opaque; + pci_device_save(&proxy->pci_dev, f); + msix_save(&proxy->pci_dev, f); + if (msix_present(&proxy->pci_dev)) + qemu_put_be16(f, proxy->vdev->config_vector); +} + +static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f) +{ + VirtIOPCIProxy *proxy = opaque; + if (msix_present(&proxy->pci_dev)) + qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n)); +} + +static int virtio_pci_load_config(void * opaque, QEMUFile *f) +{ + VirtIOPCIProxy *proxy = opaque; + int ret; + ret = pci_device_load(&proxy->pci_dev, f); + if (ret) + return ret; + ret = msix_load(&proxy->pci_dev, f); + if (ret) + return ret; + if (msix_present(&proxy->pci_dev)) + qemu_get_be16s(f, &proxy->vdev->config_vector); + return 0; +} + +static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f) +{ + VirtIOPCIProxy *proxy = opaque; + uint16_t vector; + if (!msix_present(&proxy->pci_dev)) + return 0; + qemu_get_be16s(f, &vector); + virtio_queue_set_vector(proxy->vdev, n, vector); + return 0; +} + static void virtio_pci_reset(void *opaque) { VirtIOPCIProxy *proxy = opaque; @@ -317,7 +359,12 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, } static const VirtIOBindings virtio_pci_bindings = { - .notify = virtio_pci_notify + .notify = virtio_pci_notify, + .save_config = virtio_pci_save_config, + .load_config = virtio_pci_load_config, + .save_config = virtio_pci_save_config, + .save_queue = virtio_pci_save_queue, + .load_queue = virtio_pci_load_queue, }; static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, diff --git a/hw/virtio.c b/hw/virtio.c index 63ffcff..b773dff 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -568,9 +568,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) { int i; - /* FIXME: load/save binding. */ - //pci_device_save(&vdev->pci_dev, f); - //msix_save(&vdev->pci_dev, f); + if (vdev->binding->save_config) + vdev->binding->save_config(vdev->binding_opaque, f); qemu_put_8s(f, &vdev->status); qemu_put_8s(f, &vdev->isr); @@ -596,19 +595,20 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) qemu_put_be32(f, vdev->vq[i].vring.num); qemu_put_be64(f, vdev->vq[i].pa); qemu_put_be16s(f, &vdev->vq[i].last_avail_idx); - if (vdev->nvectors) - qemu_put_be16s(f, &vdev->vq[i].vector); + if (vdev->binding->save_queue) + vdev->binding->save_queue(vdev->binding_opaque, i, f); } } int virtio_load(VirtIODevice *vdev, QEMUFile *f) { - int num, i; + int num, i, ret; - /* FIXME: load/save binding. */ - //pci_device_load(&vdev->pci_dev, f); - //r = msix_load(&vdev->pci_dev, f); - //pci_resize_io_region(&vdev->pci_dev, 1, msix_bar_size(&vdev->pci_dev)); + if (vdev->binding->load_config) { + ret = vdev->binding->load_config(vdev->binding_opaque, f); + if (ret) + return ret; + } qemu_get_8s(f, &vdev->status); qemu_get_8s(f, &vdev->isr); @@ -617,10 +617,6 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) vdev->config_len = qemu_get_be32(f); qemu_get_buffer(f, vdev->config, vdev->config_len); - if (vdev->nvectors) { - qemu_get_be16s(f, &vdev->config_vector); - //msix_vector_use(&vdev->pci_dev, vdev->config_vector); - } num = qemu_get_be32(f); for (i = 0; i < num; i++) { @@ -631,9 +627,10 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) if (vdev->vq[i].pa) { virtqueue_init(&vdev->vq[i]); } - if (vdev->nvectors) { - qemu_get_be16s(f, &vdev->vq[i].vector); - //msix_vector_use(&vdev->pci_dev, vdev->config_vector); + if (vdev->binding->load_queue) { + ret = vdev->binding->load_queue(vdev->binding_opaque, i, f); + if (ret) + return ret; } } diff --git a/hw/virtio.h b/hw/virtio.h index 04a3c3d..ce05517 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -72,6 +72,10 @@ typedef struct VirtQueueElement typedef struct { void (*notify)(void * opaque, uint16_t vector); + void (*save_config)(void * opaque, QEMUFile *f); + void (*save_queue)(void * opaque, int n, QEMUFile *f); + int (*load_config)(void * opaque, QEMUFile *f); + int (*load_queue)(void * opaque, int n, QEMUFile *f); } VirtIOBindings; #define VIRTIO_PCI_QUEUE_MAX 16