summaryrefslogtreecommitdiffstats
path: root/hw/ppc/spapr.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc/spapr.c')
-rw-r--r--hw/ppc/spapr.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ff87f155d5..d682f013d4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -353,8 +353,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
cpus_offset = fdt_path_offset(fdt, "/cpus");
if (cpus_offset < 0) {
- cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"),
- "cpus");
+ cpus_offset = fdt_add_subnode(fdt, 0, "cpus");
if (cpus_offset < 0) {
return cpus_offset;
}
@@ -820,6 +819,13 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
return 1;
}
+ if (size < sizeof(hdr) || size > FW_MAX_SIZE) {
+ error_report("SLOF provided an unexpected CAS buffer size "
+ TARGET_FMT_lu " (min: %zu, max: %u)",
+ size, sizeof(hdr), FW_MAX_SIZE);
+ exit(EXIT_FAILURE);
+ }
+
size -= sizeof(hdr);
/* Create skeleton */
@@ -2123,7 +2129,7 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
- char *type = spapr_get_cpu_core_type(machine->cpu_model);
+ const char *type = spapr_get_cpu_core_type(machine->cpu_type);
int smt = kvmppc_smt_threads();
const CPUArchIdList *possible_cpus;
int boot_cores_nr = smp_cpus / smp_threads;
@@ -2178,7 +2184,6 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
object_property_set_bool(core, true, "realized", &error_fatal);
}
}
- g_free(type);
}
static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
@@ -2335,7 +2340,8 @@ static void ppc_spapr_init(MachineState *machine)
/* Set up Interrupt Controller before we create the VCPUs */
xics_system_init(machine, XICS_IRQS_SPAPR, &error_fatal);
- /* Set up containers for ibm,client-set-architecture negotiated options */
+ /* Set up containers for ibm,client-architecture-support negotiated options
+ */
spapr->ov5 = spapr_ovec_new();
spapr->ov5_cas = spapr_ovec_new();
@@ -2362,12 +2368,6 @@ static void ppc_spapr_init(MachineState *machine)
}
/* init CPUs */
- if (machine->cpu_model == NULL) {
- machine->cpu_model = kvm_enabled() ? "host" : smc->tcg_default_cpu;
- }
-
- spapr_cpu_parse_features(spapr);
-
spapr_set_vsmt_mode(spapr, &error_fatal);
spapr_init_cpus(spapr);
@@ -3054,14 +3054,13 @@ void spapr_lmb_release(DeviceState *dev)
return;
}
- spapr_pending_dimm_unplugs_remove(spapr, ds);
-
/*
* Now that all the LMBs have been removed by the guest, call the
* pc-dimm unplug handler to cleanup up the pc-dimm device.
*/
pc_dimm_memory_unplug(dev, &spapr->hotplug_memory, mr);
object_unparent(OBJECT(dev));
+ spapr_pending_dimm_unplugs_remove(spapr, ds);
}
static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
@@ -3090,6 +3089,19 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
goto out;
}
+ /*
+ * An existing pending dimm state for this DIMM means that there is an
+ * unplug operation in progress, waiting for the spapr_lmb_release
+ * callback to complete the job (BQL can't cover that far). In this case,
+ * bail out to avoid detaching DRCs that were already released.
+ */
+ if (spapr_pending_dimm_unplugs_find(spapr, dimm)) {
+ error_setg(&local_err,
+ "Memory unplug already in progress for device %s",
+ dev->id);
+ goto out;
+ }
+
spapr_pending_dimm_unplugs_add(spapr, nr_lmbs, dimm);
addr = addr_start;
@@ -3142,8 +3154,7 @@ void spapr_core_release(DeviceState *dev)
if (smc->pre_2_10_has_unused_icps) {
sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(cc));
- const char *typename = object_class_get_name(scc->cpu_class);
- size_t size = object_type_get_instance_size(typename);
+ size_t size = object_type_get_instance_size(scc->cpu_type);
int i;
for (i = 0; i < cc->nr_threads; i++) {
@@ -3239,8 +3250,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
if (smc->pre_2_10_has_unused_icps) {
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(cc));
- const char *typename = object_class_get_name(scc->cpu_class);
- size_t size = object_type_get_instance_size(typename);
+ size_t size = object_type_get_instance_size(scc->cpu_type);
int i;
for (i = 0; i < cc->nr_threads; i++) {
@@ -3260,7 +3270,7 @@ static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
Error *local_err = NULL;
CPUCore *cc = CPU_CORE(dev);
- char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model);
+ const char *base_core_type = spapr_get_cpu_core_type(machine->cpu_type);
const char *type = object_get_typename(OBJECT(dev));
CPUArchId *core_slot;
int index;
@@ -3306,7 +3316,6 @@ static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
numa_cpu_pre_plug(core_slot, dev, &local_err);
out:
- g_free(base_core_type);
error_propagate(errp, local_err);
}
@@ -3605,7 +3614,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
hc->unplug_request = spapr_machine_device_unplug_request;
smc->dr_lmb_enabled = true;
- smc->tcg_default_cpu = "POWER8";
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
mc->has_hotpluggable_cpus = true;
smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
fwc->get_dev_path = spapr_get_fw_dev_path;
@@ -3851,7 +3860,7 @@ static void spapr_machine_2_7_class_options(MachineClass *mc)
sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_2_8_class_options(mc);
- smc->tcg_default_cpu = "POWER7";
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power7_v2.3");
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_7);
smc->phb_placement = phb_placement_2_7;
}