Commit ff24bd589c657ad82ae0f151c4906f120a91f6f3
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>
Showing
3 changed files
with
65 additions
and
18 deletions
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 |