aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/core/machine.c3
-rw-r--r--hw/core/qdev-properties.c4
-rw-r--r--hw/core/qdev.c8
-rw-r--r--hw/i386/pc.c38
-rw-r--r--hw/ide/core.c1
-rw-r--r--hw/nvram/spapr_nvram.c23
-rw-r--r--hw/ppc/spapr.c19
-rw-r--r--hw/ppc/spapr_cpu_core.c24
-rw-r--r--hw/virtio/virtio.c5
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);