diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 3e7fba3822c50d52af557c3cb4437ad825d76a20..a3133211a89c4bd95246cc001841261bd7da1bc7 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -551,6 +551,12 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm) (1 << ACPI_FADT_F_SLP_BUTTON) | (1 << ACPI_FADT_F_RTC_S4)); fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_USE_PLATFORM_CLOCK); + /* APIC destination mode ("Flat Logical") has an upper limit of 8 CPUs + * For more than 8 CPUs, "Clustered Logical" mode has to be used + */ + if (max_cpus > 8) { + fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL); + } } diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 9bbf2ee4ce07d44063ed66f432574f498914ae43..b21e7a434f90b788f408cf9de9e1bd81f3c821e8 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -115,6 +115,7 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features) void vhost_net_ack_features(struct vhost_net *net, unsigned features) { + net->dev.acked_features = net->dev.backend_features; vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features); } @@ -188,16 +189,19 @@ bool vhost_net_query(VHostNetState *net, VirtIODevice *dev) return vhost_dev_query(&net->dev, dev); } +static void vhost_net_set_vq_index(struct vhost_net *net, int vq_index) +{ + net->dev.vq_index = vq_index; +} + static int vhost_net_start_one(struct vhost_net *net, - VirtIODevice *dev, - int vq_index) + VirtIODevice *dev) { struct vhost_vring_file file = { }; int r; net->dev.nvqs = 2; net->dev.vqs = net->vqs; - net->dev.vq_index = vq_index; r = vhost_dev_enable_notifiers(&net->dev, dev); if (r < 0) { @@ -286,7 +290,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev))); VirtioBusState *vbus = VIRTIO_BUS(qbus); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus); - int r, i = 0; + int r, e, i; if (!vhost_net_device_endian_ok(dev)) { error_report("vhost-net does not support cross-endian"); @@ -301,11 +305,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, } for (i = 0; i < total_queues; i++) { - r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev, i * 2); - - if (r < 0) { - goto err; - } + vhost_net_set_vq_index(get_vhost_net(ncs[i].peer), i * 2); } r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true); @@ -314,12 +314,26 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, goto err; } + for (i = 0; i < total_queues; i++) { + r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev); + + if (r < 0) { + goto err_start; + } + } + return 0; -err: +err_start: while (--i >= 0) { vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev); } + e = k->set_guest_notifiers(qbus->parent, total_queues * 2, false); + if (e < 0) { + fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e); + fflush(stderr); + } +err: return r; } @@ -331,16 +345,16 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs, VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus); int i, r; + for (i = 0; i < total_queues; i++) { + vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev); + } + r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false); if (r < 0) { fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r); fflush(stderr); } assert(r >= 0); - - for (i = 0; i < total_queues; i++) { - vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev); - } } void vhost_net_cleanup(struct vhost_net *net) diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index ddfe76aed01b0a2ed5fa709ade3badba753ac854..7146e0ec49b392834a4a1320dcae72a5ba468c9b 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -238,6 +238,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) s->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs); s->dev.vq_index = 0; + s->dev.backend_features = 0; ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd, VHOST_BACKEND_TYPE_KERNEL, true); @@ -246,7 +247,6 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) strerror(-ret)); return; } - s->dev.backend_features = 0; error_setg(&s->migration_blocker, "vhost-scsi does not support migration"); diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index e55fe1cc7eb05eae0ce0b01fdd9e25eed946ea05..5d7c40ac04d06f48e604d4d8c6ce9d054f847104 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -976,7 +976,6 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n) { struct vhost_virtqueue *vq = hdev->vqs + n - hdev->vq_index; - assert(hdev->started); assert(n >= hdev->vq_index && n < hdev->vq_index + hdev->nvqs); return event_notifier_test_and_clear(&vq->masked_notifier); } @@ -988,7 +987,6 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, struct VirtQueue *vvq = virtio_get_queue(vdev, n); int r, index = n - hdev->vq_index; - assert(hdev->started); assert(n >= hdev->vq_index && n < hdev->vq_index + hdev->nvqs); struct vhost_vring_file file = {