diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/core/machine.c | 3 | ||||
-rw-r--r-- | hw/core/qdev-properties.c | 4 | ||||
-rw-r--r-- | hw/core/qdev.c | 8 | ||||
-rw-r--r-- | hw/i386/pc.c | 38 | ||||
-rw-r--r-- | hw/ide/core.c | 1 | ||||
-rw-r--r-- | hw/nvram/spapr_nvram.c | 23 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 19 | ||||
-rw-r--r-- | hw/ppc/spapr_cpu_core.c | 24 | ||||
-rw-r--r-- | hw/virtio/virtio.c | 5 |
9 files changed, 61 insertions, 64 deletions
diff --git a/hw/core/machine.c b/hw/core/machine.c index 2fe6ff6f30..e5a456f21d 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -65,6 +65,9 @@ static void machine_set_kernel_irqchip(Object *obj, Visitor *v, ms->kernel_irqchip_split = true; break; default: + /* The value was checked in visit_type_OnOffSplit() above. If + * we get here, then something is wrong in QEMU. + */ abort(); } } diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 14e544ab17..311af6da76 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -1084,7 +1084,7 @@ int qdev_prop_check_globals(void) } static void qdev_prop_set_globals_for_type(DeviceState *dev, - const char *typename) + const char *typename) { GList *l; @@ -1100,7 +1100,7 @@ static void qdev_prop_set_globals_for_type(DeviceState *dev, if (err != NULL) { error_prepend(&err, "can't apply global %s.%s=%s: ", prop->driver, prop->property, prop->value); - if (prop->errp) { + if (!dev->hotplugged && prop->errp) { error_propagate(prop->errp, err); } else { assert(prop->user_provided); diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 6680089154..ee4a083e64 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -885,6 +885,8 @@ static void device_set_realized(Object *obj, bool value, Error **errp) HotplugHandler *hotplug_ctrl; BusState *bus; Error *local_err = NULL; + bool unattached_parent = false; + static int unattached_count; if (dev->hotplugged && !dc->hotpluggable) { error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj)); @@ -893,12 +895,12 @@ static void device_set_realized(Object *obj, bool value, Error **errp) if (value && !dev->realized) { if (!obj->parent) { - static int unattached_count; gchar *name = g_strdup_printf("device[%d]", unattached_count++); object_property_add_child(container_get(qdev_get_machine(), "/unattached"), name, obj, &error_abort); + unattached_parent = true; g_free(name); } @@ -987,6 +989,10 @@ post_realize_fail: fail: error_propagate(errp, local_err); + if (unattached_parent) { + object_unparent(OBJECT(dev)); + unattached_count--; + } } static bool device_get_hotpluggable(Object *obj, Error **errp) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9e3c70fb23..47593b741a 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1818,23 +1818,6 @@ static void pc_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, goto out; } - if (idx < pcms->possible_cpus->len - 1 && - pcms->possible_cpus->cpus[idx + 1].cpu != NULL) { - X86CPU *cpu; - - for (idx = pcms->possible_cpus->len - 1; - pcms->possible_cpus->cpus[idx].cpu == NULL; idx--) { - ;; - } - - cpu = X86_CPU(pcms->possible_cpus->cpus[idx].cpu); - error_setg(&local_err, "CPU [socket-id: %u, core-id: %u," - " thread-id: %u] should be removed first", - cpu->socket_id, cpu->core_id, cpu->thread_id); - goto out; - - } - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); @@ -1875,6 +1858,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { int idx; + CPUState *cs; CPUArchId *cpu_slot; X86CPUTopoInfo topo; X86CPU *cpu = X86_CPU(dev); @@ -1931,23 +1915,6 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, return; } - if (idx != 0 && pcms->possible_cpus->cpus[idx - 1].cpu == NULL) { - PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); - - for (idx = 1; pcms->possible_cpus->cpus[idx].cpu != NULL; idx++) { - ;; - } - - x86_topo_ids_from_apicid(pcms->possible_cpus->cpus[idx].arch_id, - smp_cores, smp_threads, &topo); - - if (!pcmc->legacy_cpu_hotplug) { - error_setg(errp, "CPU [socket: %u, core: %u, thread: %u] should be" - " added first", topo.pkg_id, topo.core_id, topo.smt_id); - return; - } - } - /* if 'address' properties socket-id/core-id/thread-id are not set, set them * so that query_hotpluggable_cpus would show correct values */ @@ -1975,6 +1942,9 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, return; } cpu->thread_id = topo.smt_id; + + cs = CPU(cpu); + cs->cpu_index = idx; } static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, diff --git a/hw/ide/core.c b/hw/ide/core.c index 081c9eb765..d117b7c202 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -823,6 +823,7 @@ static void ide_dma_cb(void *opaque, int ret) } if (ret < 0) { if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) { + s->bus->dma->aiocb = NULL; return; } } diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c index 019f25dc58..4de5f705d8 100644 --- a/hw/nvram/spapr_nvram.c +++ b/hw/nvram/spapr_nvram.c @@ -39,6 +39,7 @@ typedef struct sPAPRNVRAM { uint32_t size; uint8_t *buf; BlockBackend *blk; + VMChangeStateEntry *vmstate; } sPAPRNVRAM; #define TYPE_VIO_SPAPR_NVRAM "spapr-nvram" @@ -185,19 +186,25 @@ static int spapr_nvram_pre_load(void *opaque) return 0; } +static void postload_update_cb(void *opaque, int running, RunState state) +{ + sPAPRNVRAM *nvram = opaque; + + /* This is called after bdrv_invalidate_cache_all. */ + + qemu_del_vm_change_state_handler(nvram->vmstate); + nvram->vmstate = NULL; + + blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size, 0); +} + static int spapr_nvram_post_load(void *opaque, int version_id) { sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque); if (nvram->blk) { - int alen = blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size, 0); - - if (alen < 0) { - return alen; - } - if (alen != nvram->size) { - return -1; - } + nvram->vmstate = qemu_add_vm_change_state_handler(postload_update_cb, + nvram); } return 0; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 7f33a1b2b5..fbbd0518ed 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1512,7 +1512,6 @@ static int htab_save_complete(QEMUFile *f, void *opaque) if (rc < 0) { return rc; } - close_htab_fd(spapr); } else { if (spapr->htab_first_pass) { htab_save_first_pass(f, spapr, -1); @@ -1614,10 +1613,18 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) return 0; } +static void htab_cleanup(void *opaque) +{ + sPAPRMachineState *spapr = opaque; + + close_htab_fd(spapr); +} + static SaveVMHandlers savevm_htab_handlers = { .save_live_setup = htab_save_setup, .save_live_iterate = htab_save_iterate, .save_live_complete_precopy = htab_save_complete, + .cleanup = htab_cleanup, .load_state = htab_load, }; @@ -1808,10 +1815,11 @@ static void ppc_spapr_init(MachineState *machine) spapr->cores = g_new0(Object *, spapr_max_cores); for (i = 0; i < spapr_max_cores; i++) { - int core_dt_id = i * smt; + int core_id = i * smp_threads; sPAPRDRConnector *drc = spapr_dr_connector_new(OBJECT(spapr), - SPAPR_DR_CONNECTOR_TYPE_CPU, core_dt_id); + SPAPR_DR_CONNECTOR_TYPE_CPU, + (core_id / smp_threads) * smt); qemu_register_reset(spapr_drc_reset, drc); @@ -1827,7 +1835,7 @@ static void ppc_spapr_init(MachineState *machine) core = object_new(type); object_property_set_int(core, smp_threads, "nr-threads", &error_fatal); - object_property_set_int(core, core_dt_id, CPU_CORE_PROP_CORE_ID, + object_property_set_int(core, core_id, CPU_CORE_PROP_CORE_ID, &error_fatal); object_property_set_bool(core, true, "realized", &error_fatal); } @@ -2369,7 +2377,6 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine) HotpluggableCPUList *head = NULL; sPAPRMachineState *spapr = SPAPR_MACHINE(machine); int spapr_max_cores = max_cpus / smp_threads; - int smt = kvmppc_smt_threads(); for (i = 0; i < spapr_max_cores; i++) { HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1); @@ -2379,7 +2386,7 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine) cpu_item->type = spapr_get_cpu_core_type(machine->cpu_model); cpu_item->vcpus_count = smp_threads; cpu_props->has_core_id = true; - cpu_props->core_id = i * smt; + cpu_props->core_id = i * smp_threads; /* TODO: add 'has_node/node' here to describe to which node core belongs */ diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 4bfc96bd5a..c04aaa47d7 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -103,7 +103,6 @@ static void spapr_core_release(DeviceState *dev, void *opaque) size_t size = object_type_get_instance_size(typename); sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); CPUCore *cc = CPU_CORE(dev); - int smt = kvmppc_smt_threads(); int i; for (i = 0; i < cc->nr_threads; i++) { @@ -117,7 +116,7 @@ static void spapr_core_release(DeviceState *dev, void *opaque) object_unparent(obj); } - spapr->cores[cc->core_id / smt] = NULL; + spapr->cores[cc->core_id / smp_threads] = NULL; g_free(sc->threads); object_unparent(OBJECT(dev)); @@ -128,18 +127,19 @@ void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, { sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); CPUCore *cc = CPU_CORE(dev); + int smt = kvmppc_smt_threads(); + int index = cc->core_id / smp_threads; sPAPRDRConnector *drc = - spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, cc->core_id); + spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt); sPAPRDRConnectorClass *drck; Error *local_err = NULL; - int smt = kvmppc_smt_threads(); - int index = cc->core_id / smt; int spapr_max_cores = max_cpus / smp_threads; int i; for (i = spapr_max_cores - 1; i > index; i--) { if (spapr->cores[i]) { - error_setg(errp, "core-id %d should be removed first", i * smt); + error_setg(errp, "core-id %d should be removed first", + i * smp_threads); return; } } @@ -168,11 +168,10 @@ void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error *local_err = NULL; void *fdt = NULL; int fdt_offset = 0; - int index; + int index = cc->core_id / smp_threads; int smt = kvmppc_smt_threads(); - drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, cc->core_id); - index = cc->core_id / smt; + drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt); spapr->cores[index] = OBJECT(dev); if (!smc->dr_cpu_enabled) { @@ -226,7 +225,6 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); int spapr_max_cores = max_cpus / smp_threads; int index, i; - int smt = kvmppc_smt_threads(); Error *local_err = NULL; CPUCore *cc = CPU_CORE(dev); char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model); @@ -247,12 +245,12 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, goto out; } - if (cc->core_id % smt) { + if (cc->core_id % smp_threads) { error_setg(&local_err, "invalid core id %d\n", cc->core_id); goto out; } - index = cc->core_id / smt; + index = cc->core_id / smp_threads; if (index < 0 || index >= spapr_max_cores) { error_setg(&local_err, "core id %d out of range", cc->core_id); goto out; @@ -266,7 +264,7 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, for (i = 0; i < index; i++) { if (!spapr->cores[i]) { error_setg(&local_err, "core-id %d should be added first", - i * smt); + i * smp_threads); goto out; } } diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index b4d05110d2..15ee3a71fa 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -567,6 +567,11 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz) max = vq->vring.num; + if (vq->inuse >= vq->vring.num) { + error_report("Virtqueue size exceeded"); + exit(1); + } + i = head = virtqueue_get_head(vq, vq->last_avail_idx++); if (virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) { vring_set_avail_event(vq, vq->last_avail_idx); |