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 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 148 static void virtio_pci_reset(void *opaque)
109 149 {
110 150 VirtIOPCIProxy *proxy = opaque;
... ... @@ -319,7 +359,11 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
319 359 }
320 360  
321 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 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 616 {
617 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 622 qemu_put_8s(f, &vdev->status);
624 623 qemu_put_8s(f, &vdev->isr);
... ... @@ -644,18 +643,20 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
644 643 qemu_put_be32(f, vdev->vq[i].vring.num);
645 644 qemu_put_be64(f, vdev->vq[i].pa);
646 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 661 qemu_get_8s(f, &vdev->status);
661 662 qemu_get_8s(f, &vdev->isr);
... ... @@ -664,10 +665,6 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
664 665 vdev->config_len = qemu_get_be32(f);
665 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 668 num = qemu_get_be32(f);
672 669  
673 670 for (i = 0; i < num; i++) {
... ... @@ -678,13 +675,15 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
678 675 if (vdev->vq[i].pa) {
679 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 685 virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
  686 + return 0;
688 687 }
689 688  
690 689 void virtio_cleanup(VirtIODevice *vdev)
... ...
hw/virtio.h
... ... @@ -76,6 +76,10 @@ typedef struct VirtQueueElement
76 76  
77 77 typedef struct {
78 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 83 } VirtIOBindings;
80 84  
81 85 #define VIRTIO_PCI_QUEUE_MAX 16
... ...