pseries kernels support hot-plugging CPUs in core granularity. i,e., when a core is hotplugged, guest kernel tries to bring up all the threads in that core. This doesn't match 1-to-1 with QEMU hotplug semantics where cpu-add monitor command hotplugs 1 CPU at a time.
While it is still an open question as to what kind of CPU hotplug semantics we should support here, this patch restricts cpu-add monitor command to allow only CPU cores to be added. All the threads of the hot-plugged core at onlined at once. Signed-off-by: Bharata B Rao <bhar...@linux.vnet.ibm.com> --- hw/ppc/spapr.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9a3d1ca..96fb11b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1717,7 +1717,7 @@ static int spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset) return 0; } -static void spapr_cpu_hotplug_add(CPUState *cs) +static int spapr_cpu_hotplug_add(CPUState *cs) { int i, j; sPAPRDrcEntry *drc_entry; @@ -1740,6 +1740,11 @@ static void spapr_cpu_hotplug_add(CPUState *cs) PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); char *nodename; int index = ppc_get_vcpu_dt_id(cpu); + int smt = kvmppc_smt_threads(); + + if ((index % smt) != 0) { + return -1; + } drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id + SPAPR_DRC_CPU_ID_BASE); g_assert(drc_entry); @@ -1797,14 +1802,17 @@ static void spapr_cpu_hotplug_add(CPUState *cs) ccs->fdt = fdt; ccs->offset_start = offset; ccs->state = CC_STATE_PENDING; + + return 0; } static void spapr_cpu_added_req(Notifier *n, void *opaque) { CPUState *cs = CPU(opaque); - spapr_cpu_hotplug_add(cs); - spapr_cpu_hotplug_add_event(cs); + if (!spapr_cpu_hotplug_add(cs)) { + spapr_cpu_hotplug_add_event(cs); + } return; } @@ -2193,6 +2201,7 @@ static void ppc_hot_add_cpu(const int64_t id, Error **errp) { CPUState *cs; PowerPCCPU *cpu; + int i; if (id < 0) { error_setg(errp, "Invalid CPU id: %" PRIi64, id); @@ -2213,8 +2222,16 @@ static void ppc_hot_add_cpu(const int64_t id, Error **errp) return; } - cpu = ppc_new_cpu(current_cpu_model); - spapr_cpu_reset(cpu); + if ((id % smp_threads) != 0) { + error_setg(errp, "Invalid CPU id: %" PRIi64 + ", only cores can be added", id); + return; + } + + for (i = 0; i < smp_threads; i++) { + cpu = ppc_new_cpu(current_cpu_model); + spapr_cpu_reset(cpu); + } } static void spapr_machine_class_init(ObjectClass *oc, void *data) -- 1.7.11.7