~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to hw/virtio/virtio-pci.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-01-27 09:10:37 UTC
  • Revision ID: package-import@ubuntu.com-20140127091037-qf1lsx2iau13d3sk
Tags: 1.7.0+dfsg-2ubuntu8
* SECURITY UPDATE: denial of service via virtio device hot-plugging
  - debian/patches/CVE-2013-4377.patch: upstream commits to refactor
    virtio device unplugging.
  - CVE-2013-4377

Show diffs side-by-side

added added

removed removed

Lines of Context:
113
113
static void virtio_pci_notify(DeviceState *d, uint16_t vector)
114
114
{
115
115
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d);
 
116
 
116
117
    if (msix_enabled(&proxy->pci_dev))
117
118
        msix_notify(&proxy->pci_dev, vector);
118
 
    else
119
 
        pci_set_irq(&proxy->pci_dev, proxy->vdev->isr & 1);
 
119
    else {
 
120
        VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
121
        pci_set_irq(&proxy->pci_dev, vdev->isr & 1);
 
122
    }
120
123
}
121
124
 
122
125
static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
123
126
{
124
127
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 
128
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
129
 
125
130
    pci_device_save(&proxy->pci_dev, f);
126
131
    msix_save(&proxy->pci_dev, f);
127
132
    if (msix_present(&proxy->pci_dev))
128
 
        qemu_put_be16(f, proxy->vdev->config_vector);
 
133
        qemu_put_be16(f, vdev->config_vector);
129
134
}
130
135
 
131
136
static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
132
137
{
133
138
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 
139
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
140
 
134
141
    if (msix_present(&proxy->pci_dev))
135
 
        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
 
142
        qemu_put_be16(f, virtio_queue_vector(vdev, n));
136
143
}
137
144
 
138
145
static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
139
146
{
140
147
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 
148
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
149
 
141
150
    int ret;
142
151
    ret = pci_device_load(&proxy->pci_dev, f);
143
152
    if (ret) {
146
155
    msix_unuse_all_vectors(&proxy->pci_dev);
147
156
    msix_load(&proxy->pci_dev, f);
148
157
    if (msix_present(&proxy->pci_dev)) {
149
 
        qemu_get_be16s(f, &proxy->vdev->config_vector);
 
158
        qemu_get_be16s(f, &vdev->config_vector);
150
159
    } else {
151
 
        proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
 
160
        vdev->config_vector = VIRTIO_NO_VECTOR;
152
161
    }
153
 
    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
154
 
        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
 
162
    if (vdev->config_vector != VIRTIO_NO_VECTOR) {
 
163
        return msix_vector_use(&proxy->pci_dev, vdev->config_vector);
155
164
    }
156
165
    return 0;
157
166
}
159
168
static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
160
169
{
161
170
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 
171
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
172
 
162
173
    uint16_t vector;
163
174
    if (msix_present(&proxy->pci_dev)) {
164
175
        qemu_get_be16s(f, &vector);
165
176
    } else {
166
177
        vector = VIRTIO_NO_VECTOR;
167
178
    }
168
 
    virtio_queue_set_vector(proxy->vdev, n, vector);
 
179
    virtio_queue_set_vector(vdev, n, vector);
169
180
    if (vector != VIRTIO_NO_VECTOR) {
170
181
        return msix_vector_use(&proxy->pci_dev, vector);
171
182
    }
175
186
static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
176
187
                                                 int n, bool assign, bool set_handler)
177
188
{
178
 
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
 
189
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
190
    VirtQueue *vq = virtio_get_queue(vdev, n);
179
191
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
180
192
    int r = 0;
181
193
 
200
212
 
201
213
static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
202
214
{
 
215
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
203
216
    int n, r;
204
217
 
205
218
    if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
209
222
    }
210
223
 
211
224
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
212
 
        if (!virtio_queue_get_num(proxy->vdev, n)) {
 
225
        if (!virtio_queue_get_num(vdev, n)) {
213
226
            continue;
214
227
        }
215
228
 
223
236
 
224
237
assign_error:
225
238
    while (--n >= 0) {
226
 
        if (!virtio_queue_get_num(proxy->vdev, n)) {
 
239
        if (!virtio_queue_get_num(vdev, n)) {
227
240
            continue;
228
241
        }
229
242
 
236
249
 
237
250
static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
238
251
{
 
252
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
239
253
    int r;
240
254
    int n;
241
255
 
244
258
    }
245
259
 
246
260
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
247
 
        if (!virtio_queue_get_num(proxy->vdev, n)) {
 
261
        if (!virtio_queue_get_num(vdev, n)) {
248
262
            continue;
249
263
        }
250
264
 
257
271
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
258
272
{
259
273
    VirtIOPCIProxy *proxy = opaque;
260
 
    VirtIODevice *vdev = proxy->vdev;
 
274
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
261
275
    hwaddr pa;
262
276
 
263
277
    switch (addr) {
272
286
        pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
273
287
        if (pa == 0) {
274
288
            virtio_pci_stop_ioeventfd(proxy);
275
 
            virtio_reset(proxy->vdev);
 
289
            virtio_reset(vdev);
276
290
            msix_unuse_all_vectors(&proxy->pci_dev);
277
291
        }
278
292
        else
299
313
        }
300
314
 
301
315
        if (vdev->status == 0) {
302
 
            virtio_reset(proxy->vdev);
 
316
            virtio_reset(vdev);
303
317
            msix_unuse_all_vectors(&proxy->pci_dev);
304
318
        }
305
319
 
335
349
 
336
350
static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
337
351
{
338
 
    VirtIODevice *vdev = proxy->vdev;
 
352
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
339
353
    uint32_t ret = 0xFFFFFFFF;
340
354
 
341
355
    switch (addr) {
381
395
                                       unsigned size)
382
396
{
383
397
    VirtIOPCIProxy *proxy = opaque;
 
398
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
384
399
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
385
400
    uint64_t val = 0;
386
401
    if (addr < config) {
390
405
 
391
406
    switch (size) {
392
407
    case 1:
393
 
        val = virtio_config_readb(proxy->vdev, addr);
 
408
        val = virtio_config_readb(vdev, addr);
394
409
        break;
395
410
    case 2:
396
 
        val = virtio_config_readw(proxy->vdev, addr);
 
411
        val = virtio_config_readw(vdev, addr);
397
412
        if (virtio_is_big_endian()) {
398
413
            val = bswap16(val);
399
414
        }
400
415
        break;
401
416
    case 4:
402
 
        val = virtio_config_readl(proxy->vdev, addr);
 
417
        val = virtio_config_readl(vdev, addr);
403
418
        if (virtio_is_big_endian()) {
404
419
            val = bswap32(val);
405
420
        }
413
428
{
414
429
    VirtIOPCIProxy *proxy = opaque;
415
430
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
 
431
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
416
432
    if (addr < config) {
417
433
        virtio_ioport_write(proxy, addr, val);
418
434
        return;
424
440
     */
425
441
    switch (size) {
426
442
    case 1:
427
 
        virtio_config_writeb(proxy->vdev, addr, val);
 
443
        virtio_config_writeb(vdev, addr, val);
428
444
        break;
429
445
    case 2:
430
446
        if (virtio_is_big_endian()) {
431
447
            val = bswap16(val);
432
448
        }
433
 
        virtio_config_writew(proxy->vdev, addr, val);
 
449
        virtio_config_writew(vdev, addr, val);
434
450
        break;
435
451
    case 4:
436
452
        if (virtio_is_big_endian()) {
437
453
            val = bswap32(val);
438
454
        }
439
 
        virtio_config_writel(proxy->vdev, addr, val);
 
455
        virtio_config_writel(vdev, addr, val);
440
456
        break;
441
457
    }
442
458
}
455
471
                                uint32_t val, int len)
456
472
{
457
473
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
 
474
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
458
475
 
459
476
    pci_default_write_config(pci_dev, address, val, len);
460
477
 
462
479
        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
463
480
        !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
464
481
        virtio_pci_stop_ioeventfd(proxy);
465
 
        virtio_set_status(proxy->vdev,
466
 
                          proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
 
482
        virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
467
483
    }
468
484
}
469
485
 
506
522
                                 unsigned int vector)
507
523
{
508
524
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
509
 
    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
 
525
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
526
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
510
527
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
511
528
    int ret;
512
529
    ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq);
517
534
                                      unsigned int queue_no,
518
535
                                      unsigned int vector)
519
536
{
520
 
    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
 
537
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
538
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
521
539
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
522
540
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
523
541
    int ret;
529
547
static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
530
548
{
531
549
    PCIDevice *dev = &proxy->pci_dev;
532
 
    VirtIODevice *vdev = proxy->vdev;
 
550
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
533
551
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
534
552
    unsigned int vector;
535
553
    int ret, queue_no;
578
596
static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
579
597
{
580
598
    PCIDevice *dev = &proxy->pci_dev;
581
 
    VirtIODevice *vdev = proxy->vdev;
 
599
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
582
600
    unsigned int vector;
583
601
    int queue_no;
584
602
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
606
624
                                       unsigned int vector,
607
625
                                       MSIMessage msg)
608
626
{
609
 
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
610
 
    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
 
627
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
628
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
 
629
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
611
630
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
612
631
    VirtIOIRQFD *irqfd;
613
632
    int ret = 0;
626
645
     * Otherwise, set it up now.
627
646
     */
628
647
    if (k->guest_notifier_mask) {
629
 
        k->guest_notifier_mask(proxy->vdev, queue_no, false);
 
648
        k->guest_notifier_mask(vdev, queue_no, false);
630
649
        /* Test after unmasking to avoid losing events. */
631
650
        if (k->guest_notifier_pending &&
632
 
            k->guest_notifier_pending(proxy->vdev, queue_no)) {
 
651
            k->guest_notifier_pending(vdev, queue_no)) {
633
652
            event_notifier_set(n);
634
653
        }
635
654
    } else {
642
661
                                             unsigned int queue_no,
643
662
                                             unsigned int vector)
644
663
{
645
 
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
 
664
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
665
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
646
666
 
647
667
    /* If guest supports masking, keep irqfd but mask it.
648
668
     * Otherwise, clean it up now.
649
669
     */ 
650
670
    if (k->guest_notifier_mask) {
651
 
        k->guest_notifier_mask(proxy->vdev, queue_no, true);
 
671
        k->guest_notifier_mask(vdev, queue_no, true);
652
672
    } else {
653
673
        kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
654
674
    }
658
678
                                    MSIMessage msg)
659
679
{
660
680
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
661
 
    VirtIODevice *vdev = proxy->vdev;
 
681
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
662
682
    int ret, queue_no;
663
683
 
664
684
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
688
708
static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
689
709
{
690
710
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
691
 
    VirtIODevice *vdev = proxy->vdev;
 
711
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
692
712
    int queue_no;
693
713
 
694
714
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
707
727
                                   unsigned int vector_end)
708
728
{
709
729
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
710
 
    VirtIODevice *vdev = proxy->vdev;
 
730
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
711
731
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
712
732
    int queue_no;
713
733
    unsigned int vector;
739
759
                                         bool with_irqfd)
740
760
{
741
761
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
742
 
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
743
 
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
 
762
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
763
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
 
764
    VirtQueue *vq = virtio_get_queue(vdev, n);
744
765
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
745
766
 
746
767
    if (assign) {
755
776
    }
756
777
 
757
778
    if (!msix_enabled(&proxy->pci_dev) && vdc->guest_notifier_mask) {
758
 
        vdc->guest_notifier_mask(proxy->vdev, n, !assign);
 
779
        vdc->guest_notifier_mask(vdev, n, !assign);
759
780
    }
760
781
 
761
782
    return 0;
770
791
static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
771
792
{
772
793
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
773
 
    VirtIODevice *vdev = proxy->vdev;
 
794
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
774
795
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
775
796
    int r, n;
776
797
    bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
864
885
static void virtio_pci_vmstate_change(DeviceState *d, bool running)
865
886
{
866
887
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 
888
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
867
889
 
868
890
    if (running) {
869
891
        /* Try to find out if the guest has bus master disabled, but is
870
892
           in ready state. Then we have a buggy guest OS. */
871
 
        if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
 
893
        if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
872
894
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
873
895
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
874
896
        }
943
965
    uint8_t *config;
944
966
    uint32_t size;
945
967
 
946
 
    proxy->vdev = bus->vdev;
947
 
 
948
968
    config = proxy->pci_dev.config;
949
969
    if (proxy->class_code) {
950
970
        pci_config_set_class(config, proxy->class_code);
982
1002
                                                      proxy->host_features);
983
1003
}
984
1004
 
 
1005
static void virtio_pci_device_unplugged(DeviceState *d)
 
1006
{
 
1007
    PCIDevice *pci_dev = PCI_DEVICE(d);
 
1008
    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
 
1009
 
 
1010
    virtio_pci_stop_ioeventfd(proxy);
 
1011
    msix_uninit_exclusive_bar(pci_dev);
 
1012
}
 
1013
 
985
1014
static int virtio_pci_init(PCIDevice *pci_dev)
986
1015
{
987
1016
    VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
996
1025
static void virtio_pci_exit(PCIDevice *pci_dev)
997
1026
{
998
1027
    VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
999
 
    virtio_pci_stop_ioeventfd(proxy);
1000
1028
    memory_region_destroy(&proxy->bar);
1001
 
    msix_uninit_exclusive_bar(pci_dev);
1002
1029
}
1003
1030
 
1004
1031
static void virtio_pci_reset(DeviceState *qdev)
1533
1560
    k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
1534
1561
    k->vmstate_change = virtio_pci_vmstate_change;
1535
1562
    k->device_plugged = virtio_pci_device_plugged;
 
1563
    k->device_unplugged = virtio_pci_device_unplugged;
1536
1564
}
1537
1565
 
1538
1566
static const TypeInfo virtio_pci_bus_info = {