public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] Virtio save/restore support
@ 2008-05-08 19:00 Anthony Liguori
  2008-05-08 19:00 ` [PATCH 2/3] virtio-net " Anthony Liguori
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Anthony Liguori @ 2008-05-08 19:00 UTC (permalink / raw)
  To: kvm-devel; +Cc: Avi Kivity

This patch implements the core of save/restore support for virtio.  It's
modelled after how PCI save/restore works.

N.B. This makes savevm/loadvm work, but not live migration.  The issue with
live migration is that we're manipulating guest memory without updating the
dirty bitmap correctly.  I will submit a patch in the near future that
addresses that problem.

Signed-off-by: Anthony Liguori <aliguori>

diff --git a/qemu/hw/virtio.c b/qemu/hw/virtio.c
index a4c9d10..440cc69 100644
--- a/qemu/hw/virtio.c
+++ b/qemu/hw/virtio.c
@@ -420,7 +420,6 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
 
     vdev->vq[i].vring.num = queue_size;
     vdev->vq[i].handle_output = handle_output;
-    vdev->vq[i].index = i;
 
     return &vdev->vq[i];
 }
@@ -436,6 +435,71 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
     virtio_update_irq(vdev);
 }
 
+void virtio_save(VirtIODevice *vdev, QEMUFile *f)
+{
+    int i;
+
+    pci_device_save(&vdev->pci_dev, f);
+
+    qemu_put_be32s(f, &vdev->addr);
+    qemu_put_8s(f, &vdev->status);
+    qemu_put_8s(f, &vdev->isr);
+    qemu_put_be16s(f, &vdev->queue_sel);
+    qemu_put_be32s(f, &vdev->features);
+    qemu_put_be32(f, vdev->config_len);
+    qemu_put_buffer(f, vdev->config, vdev->config_len);
+
+    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
+	if (vdev->vq[i].vring.num == 0)
+	    break;
+    }
+
+    qemu_put_be32(f, i);
+
+    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
+	if (vdev->vq[i].vring.num == 0)
+	    break;
+
+	qemu_put_be32(f, vdev->vq[i].vring.num);
+	qemu_put_be32s(f, &vdev->vq[i].pfn);
+	qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
+    }	
+}
+
+void virtio_load(VirtIODevice *vdev, QEMUFile *f)
+{
+    int num, i;
+
+    pci_device_load(&vdev->pci_dev, f);
+
+    qemu_get_be32s(f, &vdev->addr);
+    qemu_get_8s(f, &vdev->status);
+    qemu_get_8s(f, &vdev->isr);
+    qemu_get_be16s(f, &vdev->queue_sel);
+    qemu_get_be32s(f, &vdev->features);
+    vdev->config_len = qemu_get_be32(f);
+    qemu_get_buffer(f, vdev->config, vdev->config_len);
+
+    num = qemu_get_be32(f);
+
+    for (i = 0; i < num; i++) {
+	vdev->vq[i].vring.num = qemu_get_be32(f);
+	qemu_get_be32s(f, &vdev->vq[i].pfn);
+	qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
+
+	if (vdev->vq[i].pfn) {
+	    size_t size;
+	    target_phys_addr_t pa;
+
+	    pa = (ram_addr_t)vdev->vq[i].pfn << TARGET_PAGE_BITS;
+	    size = virtqueue_size(vdev->vq[i].vring.num);
+	    virtqueue_init(&vdev->vq[i], virtio_map_gpa(pa, size));
+	}
+    }
+
+    virtio_update_irq(vdev);
+}
+
 VirtIODevice *virtio_init_pci(PCIBus *bus, const char *name,
 			      uint16_t vendor, uint16_t device,
 			      uint16_t subvendor, uint16_t subdevice,
diff --git a/qemu/hw/virtio.h b/qemu/hw/virtio.h
index dee97ba..ed8cfd6 100644
--- a/qemu/hw/virtio.h
+++ b/qemu/hw/virtio.h
@@ -87,7 +87,6 @@ struct VirtQueue
     uint32_t pfn;
     uint16_t last_avail_idx;
     void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
-    int index;
 };
 
 #define VIRTQUEUE_MAX_SIZE 1024
@@ -108,8 +107,6 @@ struct VirtIODevice
     PCIDevice pci_dev;
     const char *name;
     uint32_t addr;
-    uint16_t vendor;
-    uint16_t device;
     uint8_t status;
     uint8_t isr;
     uint16_t queue_sel;
@@ -140,4 +137,8 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
 
 void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
 
+void virtio_save(VirtIODevice *vdev, QEMUFile *f);
+
+void virtio_load(VirtIODevice *vdev, QEMUFile *f);
+
 #endif

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] virtio-net save/restore support
  2008-05-08 19:00 [PATCH 1/3] Virtio save/restore support Anthony Liguori
@ 2008-05-08 19:00 ` Anthony Liguori
  2008-05-08 19:00 ` [PATCH 3/3] virtio-blk " Anthony Liguori
  2008-05-08 19:03 ` [PATCH 1/3] Virtio save/restore support (v2) Anthony Liguori
  2 siblings, 0 replies; 5+ messages in thread
From: Anthony Liguori @ 2008-05-08 19:00 UTC (permalink / raw)
  To: kvm-devel; +Cc: Anthony Liguori, Avi Kivity

The only interesting bit here is that we have to ensure that we rearm the
timer if necessary.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu/hw/virtio-net.c b/qemu/hw/virtio-net.c
index d15c2f4..5fe66ac 100644
--- a/qemu/hw/virtio-net.c
+++ b/qemu/hw/virtio-net.c
@@ -207,9 +207,40 @@ static void virtio_net_tx_timer(void *opaque)
     virtio_net_flush_tx(n, n->tx_vq);
 }
 
+static void virtio_net_save(QEMUFile *f, void *opaque)
+{
+    VirtIONet *n = opaque;
+
+    virtio_save(&n->vdev, f);
+
+    qemu_put_buffer(f, n->mac, 6);
+    qemu_put_be32(f, n->tx_timer_active);
+}
+
+static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
+{
+    VirtIONet *n = opaque;
+
+    if (version_id != 1)
+	return -EINVAL;
+
+    virtio_load(&n->vdev, f);
+
+    qemu_get_buffer(f, n->mac, 6);
+    n->tx_timer_active = qemu_get_be32(f);
+
+    if (n->tx_timer_active) {
+	qemu_mod_timer(n->tx_timer,
+		       qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL);
+    }
+
+    return 0;
+}
+
 PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
 {
     VirtIONet *n;
+    static int virtio_net_id;
 
     n = (VirtIONet *)virtio_init_pci(bus, "virtio-net", 6900, 0x1000,
 				     0, VIRTIO_ID_NET,
@@ -229,5 +260,8 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
     n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n);
     n->tx_timer_active = 0;
 
+    register_savevm("virtio-net", virtio_net_id++, 1,
+		    virtio_net_save, virtio_net_load, n);
+
     return (PCIDevice *)n;
 }

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] virtio-blk save/restore support
  2008-05-08 19:00 [PATCH 1/3] Virtio save/restore support Anthony Liguori
  2008-05-08 19:00 ` [PATCH 2/3] virtio-net " Anthony Liguori
@ 2008-05-08 19:00 ` Anthony Liguori
  2008-05-08 19:03 ` [PATCH 1/3] Virtio save/restore support (v2) Anthony Liguori
  2 siblings, 0 replies; 5+ messages in thread
From: Anthony Liguori @ 2008-05-08 19:00 UTC (permalink / raw)
  To: kvm-devel; +Cc: Anthony Liguori, Avi Kivity

No additional state needs to be saved.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu/hw/virtio-blk.c b/qemu/hw/virtio-blk.c
index 048285a..148cb75 100644
--- a/qemu/hw/virtio-blk.c
+++ b/qemu/hw/virtio-blk.c
@@ -162,11 +162,30 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
     return (1 << VIRTIO_BLK_F_SEG_MAX | 1 << VIRTIO_BLK_F_GEOMETRY);
 }
 
+static void virtio_blk_save(QEMUFile *f, void *opaque)
+{
+    VirtIOBlock *s = opaque;
+    virtio_save(&s->vdev, f);
+}
+
+static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
+{
+    VirtIOBlock *s = opaque;
+
+    if (version_id != 1)
+	return -EINVAL;
+
+    virtio_load(&s->vdev, f);
+
+    return 0;
+}
+
 void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
 		      BlockDriverState *bs)
 {
     VirtIOBlock *s;
     int cylinders, heads, secs;
+    static int virtio_blk_id;
 
     s = (VirtIOBlock *)virtio_init_pci(bus, "virtio-blk", vendor, device,
 				       0, VIRTIO_ID_BLOCK,
@@ -184,5 +203,8 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
 
     virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
 
+    register_savevm("virtio-blk", virtio_blk_id++, 1,
+		    virtio_blk_save, virtio_blk_load, s);
+
     return s;
 }

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 1/3] Virtio save/restore support (v2)
  2008-05-08 19:00 [PATCH 1/3] Virtio save/restore support Anthony Liguori
  2008-05-08 19:00 ` [PATCH 2/3] virtio-net " Anthony Liguori
  2008-05-08 19:00 ` [PATCH 3/3] virtio-blk " Anthony Liguori
@ 2008-05-08 19:03 ` Anthony Liguori
  2008-05-09 15:28   ` Avi Kivity
  2 siblings, 1 reply; 5+ messages in thread
From: Anthony Liguori @ 2008-05-08 19:03 UTC (permalink / raw)
  To: kvm-devel; +Cc: Anthony Liguori, Avi Kivity

This patch implements the core of save/restore support for virtio.  It's
modelled after how PCI save/restore works.

N.B. This makes savevm/loadvm work, but not live migration.  The issue with
live migration is that we're manipulating guest memory without updating the
dirty bitmap correctly.  I will submit a patch in the near future that
addresses that problem.

Since v1, I fixed the Signed-off-by line.  Sorry about that.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu/hw/virtio.c b/qemu/hw/virtio.c
index a4c9d10..440cc69 100644
--- a/qemu/hw/virtio.c
+++ b/qemu/hw/virtio.c
@@ -420,7 +420,6 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
 
     vdev->vq[i].vring.num = queue_size;
     vdev->vq[i].handle_output = handle_output;
-    vdev->vq[i].index = i;
 
     return &vdev->vq[i];
 }
@@ -436,6 +435,71 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
     virtio_update_irq(vdev);
 }
 
+void virtio_save(VirtIODevice *vdev, QEMUFile *f)
+{
+    int i;
+
+    pci_device_save(&vdev->pci_dev, f);
+
+    qemu_put_be32s(f, &vdev->addr);
+    qemu_put_8s(f, &vdev->status);
+    qemu_put_8s(f, &vdev->isr);
+    qemu_put_be16s(f, &vdev->queue_sel);
+    qemu_put_be32s(f, &vdev->features);
+    qemu_put_be32(f, vdev->config_len);
+    qemu_put_buffer(f, vdev->config, vdev->config_len);
+
+    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
+	if (vdev->vq[i].vring.num == 0)
+	    break;
+    }
+
+    qemu_put_be32(f, i);
+
+    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
+	if (vdev->vq[i].vring.num == 0)
+	    break;
+
+	qemu_put_be32(f, vdev->vq[i].vring.num);
+	qemu_put_be32s(f, &vdev->vq[i].pfn);
+	qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
+    }	
+}
+
+void virtio_load(VirtIODevice *vdev, QEMUFile *f)
+{
+    int num, i;
+
+    pci_device_load(&vdev->pci_dev, f);
+
+    qemu_get_be32s(f, &vdev->addr);
+    qemu_get_8s(f, &vdev->status);
+    qemu_get_8s(f, &vdev->isr);
+    qemu_get_be16s(f, &vdev->queue_sel);
+    qemu_get_be32s(f, &vdev->features);
+    vdev->config_len = qemu_get_be32(f);
+    qemu_get_buffer(f, vdev->config, vdev->config_len);
+
+    num = qemu_get_be32(f);
+
+    for (i = 0; i < num; i++) {
+	vdev->vq[i].vring.num = qemu_get_be32(f);
+	qemu_get_be32s(f, &vdev->vq[i].pfn);
+	qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
+
+	if (vdev->vq[i].pfn) {
+	    size_t size;
+	    target_phys_addr_t pa;
+
+	    pa = (ram_addr_t)vdev->vq[i].pfn << TARGET_PAGE_BITS;
+	    size = virtqueue_size(vdev->vq[i].vring.num);
+	    virtqueue_init(&vdev->vq[i], virtio_map_gpa(pa, size));
+	}
+    }
+
+    virtio_update_irq(vdev);
+}
+
 VirtIODevice *virtio_init_pci(PCIBus *bus, const char *name,
 			      uint16_t vendor, uint16_t device,
 			      uint16_t subvendor, uint16_t subdevice,
diff --git a/qemu/hw/virtio.h b/qemu/hw/virtio.h
index dee97ba..ed8cfd6 100644
--- a/qemu/hw/virtio.h
+++ b/qemu/hw/virtio.h
@@ -87,7 +87,6 @@ struct VirtQueue
     uint32_t pfn;
     uint16_t last_avail_idx;
     void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
-    int index;
 };
 
 #define VIRTQUEUE_MAX_SIZE 1024
@@ -108,8 +107,6 @@ struct VirtIODevice
     PCIDevice pci_dev;
     const char *name;
     uint32_t addr;
-    uint16_t vendor;
-    uint16_t device;
     uint8_t status;
     uint8_t isr;
     uint16_t queue_sel;
@@ -140,4 +137,8 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
 
 void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
 
+void virtio_save(VirtIODevice *vdev, QEMUFile *f);
+
+void virtio_load(VirtIODevice *vdev, QEMUFile *f);
+
 #endif

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/3] Virtio save/restore support (v2)
  2008-05-08 19:03 ` [PATCH 1/3] Virtio save/restore support (v2) Anthony Liguori
@ 2008-05-09 15:28   ` Avi Kivity
  0 siblings, 0 replies; 5+ messages in thread
From: Avi Kivity @ 2008-05-09 15:28 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: kvm-devel

Anthony Liguori wrote:
> This patch implements the core of save/restore support for virtio.  It's
> modelled after how PCI save/restore works.
>
> N.B. This makes savevm/loadvm work, but not live migration.  The issue with
> live migration is that we're manipulating guest memory without updating the
> dirty bitmap correctly.  I will submit a patch in the near future that
> addresses that problem.
>
> Since v1, I fixed the Signed-off-by line.  Sorry about that.
>
>   

Applied all three patches, thanks.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-05-09 15:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-08 19:00 [PATCH 1/3] Virtio save/restore support Anthony Liguori
2008-05-08 19:00 ` [PATCH 2/3] virtio-net " Anthony Liguori
2008-05-08 19:00 ` [PATCH 3/3] virtio-blk " Anthony Liguori
2008-05-08 19:03 ` [PATCH 1/3] Virtio save/restore support (v2) Anthony Liguori
2008-05-09 15:28   ` Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox