Commit ff24bd589c657ad82ae0f151c4906f120a91f6f3

Authored by Michael S. Tsirkin
Committed by Anthony Liguori
1 parent aba800a3

qemu/virtio: virtio save/load bindings

Implement bindings for virtio save/load. Use them in virtio pci.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
hw/virtio-pci.c
@@ -105,6 +105,46 @@ static void virtio_pci_notify(void *opaque, uint16_t vector) @@ -105,6 +105,46 @@ static void virtio_pci_notify(void *opaque, uint16_t vector)
105 qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); 105 qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
106 } 106 }
107 107
  108 +static void virtio_pci_save_config(void * opaque, QEMUFile *f)
  109 +{
  110 + VirtIOPCIProxy *proxy = opaque;
  111 + pci_device_save(&proxy->pci_dev, f);
  112 + msix_save(&proxy->pci_dev, f);
  113 + if (msix_present(&proxy->pci_dev))
  114 + qemu_put_be16(f, proxy->vdev->config_vector);
  115 +}
  116 +
  117 +static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
  118 +{
  119 + VirtIOPCIProxy *proxy = opaque;
  120 + if (msix_present(&proxy->pci_dev))
  121 + qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
  122 +}
  123 +
  124 +static int virtio_pci_load_config(void * opaque, QEMUFile *f)
  125 +{
  126 + VirtIOPCIProxy *proxy = opaque;
  127 + int ret;
  128 + ret = pci_device_load(&proxy->pci_dev, f);
  129 + if (ret)
  130 + return ret;
  131 + msix_load(&proxy->pci_dev, f);
  132 + if (msix_present(&proxy->pci_dev))
  133 + qemu_get_be16s(f, &proxy->vdev->config_vector);
  134 + return 0;
  135 +}
  136 +
  137 +static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
  138 +{
  139 + VirtIOPCIProxy *proxy = opaque;
  140 + uint16_t vector;
  141 + if (!msix_present(&proxy->pci_dev))
  142 + return 0;
  143 + qemu_get_be16s(f, &vector);
  144 + virtio_queue_set_vector(proxy->vdev, n, vector);
  145 + return 0;
  146 +}
  147 +
108 static void virtio_pci_reset(void *opaque) 148 static void virtio_pci_reset(void *opaque)
109 { 149 {
110 VirtIOPCIProxy *proxy = opaque; 150 VirtIOPCIProxy *proxy = opaque;
@@ -319,7 +359,11 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, @@ -319,7 +359,11 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
319 } 359 }
320 360
321 static const VirtIOBindings virtio_pci_bindings = { 361 static const VirtIOBindings virtio_pci_bindings = {
322 - .notify = virtio_pci_notify 362 + .notify = virtio_pci_notify,
  363 + .save_config = virtio_pci_save_config,
  364 + .load_config = virtio_pci_load_config,
  365 + .save_queue = virtio_pci_save_queue,
  366 + .load_queue = virtio_pci_load_queue,
323 }; 367 };
324 368
325 static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, 369 static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
hw/virtio.c
@@ -616,9 +616,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) @@ -616,9 +616,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
616 { 616 {
617 int i; 617 int i;
618 618
619 - /* FIXME: load/save binding. */  
620 - //pci_device_save(&vdev->pci_dev, f);  
621 - //msix_save(&vdev->pci_dev, f); 619 + if (vdev->binding->save_config)
  620 + vdev->binding->save_config(vdev->binding_opaque, f);
622 621
623 qemu_put_8s(f, &vdev->status); 622 qemu_put_8s(f, &vdev->status);
624 qemu_put_8s(f, &vdev->isr); 623 qemu_put_8s(f, &vdev->isr);
@@ -644,18 +643,20 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) @@ -644,18 +643,20 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
644 qemu_put_be32(f, vdev->vq[i].vring.num); 643 qemu_put_be32(f, vdev->vq[i].vring.num);
645 qemu_put_be64(f, vdev->vq[i].pa); 644 qemu_put_be64(f, vdev->vq[i].pa);
646 qemu_put_be16s(f, &vdev->vq[i].last_avail_idx); 645 qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
647 - if (vdev->nvectors)  
648 - qemu_put_be16s(f, &vdev->vq[i].vector); 646 + if (vdev->binding->save_queue)
  647 + vdev->binding->save_queue(vdev->binding_opaque, i, f);
649 } 648 }
650 } 649 }
651 650
652 -void virtio_load(VirtIODevice *vdev, QEMUFile *f) 651 +int virtio_load(VirtIODevice *vdev, QEMUFile *f)
653 { 652 {
654 - int num, i; 653 + int num, i, ret;
655 654
656 - /* FIXME: load/save binding. */  
657 - //pci_device_load(&vdev->pci_dev, f);  
658 - //r = msix_load(&vdev->pci_dev, f); 655 + if (vdev->binding->load_config) {
  656 + ret = vdev->binding->load_config(vdev->binding_opaque, f);
  657 + if (ret)
  658 + return ret;
  659 + }
659 660
660 qemu_get_8s(f, &vdev->status); 661 qemu_get_8s(f, &vdev->status);
661 qemu_get_8s(f, &vdev->isr); 662 qemu_get_8s(f, &vdev->isr);
@@ -664,10 +665,6 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) @@ -664,10 +665,6 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
664 vdev->config_len = qemu_get_be32(f); 665 vdev->config_len = qemu_get_be32(f);
665 qemu_get_buffer(f, vdev->config, vdev->config_len); 666 qemu_get_buffer(f, vdev->config, vdev->config_len);
666 667
667 - if (vdev->nvectors) {  
668 - qemu_get_be16s(f, &vdev->config_vector);  
669 - //msix_vector_use(&vdev->pci_dev, vdev->config_vector);  
670 - }  
671 num = qemu_get_be32(f); 668 num = qemu_get_be32(f);
672 669
673 for (i = 0; i < num; i++) { 670 for (i = 0; i < num; i++) {
@@ -678,13 +675,15 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) @@ -678,13 +675,15 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
678 if (vdev->vq[i].pa) { 675 if (vdev->vq[i].pa) {
679 virtqueue_init(&vdev->vq[i]); 676 virtqueue_init(&vdev->vq[i]);
680 } 677 }
681 - if (vdev->nvectors) {  
682 - qemu_get_be16s(f, &vdev->vq[i].vector);  
683 - //msix_vector_use(&vdev->pci_dev, vdev->config_vector); 678 + if (vdev->binding->load_queue) {
  679 + ret = vdev->binding->load_queue(vdev->binding_opaque, i, f);
  680 + if (ret)
  681 + return ret;
684 } 682 }
685 } 683 }
686 684
687 virtio_notify_vector(vdev, VIRTIO_NO_VECTOR); 685 virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
  686 + return 0;
688 } 687 }
689 688
690 void virtio_cleanup(VirtIODevice *vdev) 689 void virtio_cleanup(VirtIODevice *vdev)
hw/virtio.h
@@ -76,6 +76,10 @@ typedef struct VirtQueueElement @@ -76,6 +76,10 @@ typedef struct VirtQueueElement
76 76
77 typedef struct { 77 typedef struct {
78 void (*notify)(void * opaque, uint16_t vector); 78 void (*notify)(void * opaque, uint16_t vector);
  79 + void (*save_config)(void * opaque, QEMUFile *f);
  80 + void (*save_queue)(void * opaque, int n, QEMUFile *f);
  81 + int (*load_config)(void * opaque, QEMUFile *f);
  82 + int (*load_queue)(void * opaque, int n, QEMUFile *f);
79 } VirtIOBindings; 83 } VirtIOBindings;
80 84
81 #define VIRTIO_PCI_QUEUE_MAX 16 85 #define VIRTIO_PCI_QUEUE_MAX 16