From nobody Fri Oct 24 20:18:49 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1518776147476694.7614353805631; Fri, 16 Feb 2018 02:15:47 -0800 (PST) Received: from localhost ([::1]:59132 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1emd3S-0000bb-EW for importer@patchew.org; Fri, 16 Feb 2018 05:15:46 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35510) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1emcuY-0001eO-24 for qemu-devel@nongnu.org; Fri, 16 Feb 2018 05:06:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1emcuT-0005Ey-ME for qemu-devel@nongnu.org; Fri, 16 Feb 2018 05:06:33 -0500 Received: from ozlabs.org ([2401:3900:2:1::2]:48607) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1emcuS-00057t-UU; Fri, 16 Feb 2018 05:06:29 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3zjTLk65k1z9t6X; Fri, 16 Feb 2018 21:06:22 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1518775582; bh=01FVSeRq5ingnda00fMvkdo9yT6CMDV+XF1TLpeAuZc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EYoYlZOIcXXue3g98Rufvv+AA42SKJlowp+CPwkP99Rwg3nNZdrUUJ9/al7EckUJR G5Gka6JUvA4l5WVpqjOudxEjHuJWc+zfIpZw7PIYD6h3PxVgGCN8IRpNlqwXEvsGqr UNMRum4Yy9mDDJE1knp4rGNz3RuXZAhjf72FGCmg= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 16 Feb 2018 21:06:10 +1100 Message-Id: <20180216100617.25265-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180216100617.25265-1-david@gibson.dropbear.id.au> References: <20180216100617.25265-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PULL 07/14] spapr: use spapr->vsmt to compute VCPU ids X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, surajjs@au1.ibm.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Greg Kurz Since the introduction of VSMT in 2.11, the spacing of VCPU ids between cores is controllable through a machine property instead of being only dictated by the SMT mode of the host: cpu->vcpu_id =3D (cc->core_id * spapr->vsmt / smp_threads) + i Until recently, the machine code would try to change the SMT mode of the host to be equal to VSMT or exit. This allowed the rest of the code to assume that kvmppc_smt_threads() =3D=3D spapr->vsmt is always true. Recent commit "8904e5a75005 spapr: Adjust default VSMT value for better migration compatibility" relaxed the rule. If the VSMT mode cannot be set in KVM for some reasons, but the requested CPU topology is compatible with the current SMT mode, then we let the guest run with kvmppc_smt_threads() !=3D spapr->vsmt. This breaks quite a few places in the code, in particular when calculating DRC indexes. This is what happens on a POWER host with subcores-per-core=3D2 (ie, supports up to SMT4) when passing the following topology: -smp threads=3D4,maxcpus=3D16 \ -device host-spapr-cpu-core,core-id=3D4,id=3Dcore1 \ -device host-spapr-cpu-core,core-id=3D8,id=3Dcore2 qemu-system-ppc64: warning: Failed to set KVM's VSMT mode to 8 (errno -22) This is expected since KVM is limited to SMT4, but the guest is started anyway because this topology can run on SMT4 even with a VSMT8 spacing. But when we look at the DT, things get nastier: cpus { ... ibm,drc-indexes =3D <0x4 0x10000000 0x10000004 0x10000008 0x1000000= c>; This means that we have the following association: CPU core device | DRC | VCPU id -----------------+------------+--------- boot core | 0x10000000 | 0 core1 | 0x10000004 | 4 core2 | 0x10000008 | 8 core3 | 0x1000000c | 12 But since the spacing of VCPU ids is 8, the DRC for core1 points to a VCPU that doesn't exist, the DRC for core2 points to the first VCPU of core1 and and so on... ... PowerPC,POWER8@0 { ... ibm,my-drc-index =3D <0x10000000>; ... }; PowerPC,POWER8@8 { ... ibm,my-drc-index =3D <0x10000008>; ... }; PowerPC,POWER8@10 { ... No ibm,my-drc-index property for this core since 0x10000010 doesn't exist in ibm,drc-indexes above. ... }; }; ... interrupt-controller { ... ibm,interrupt-server-ranges =3D <0x0 0x10>; With a spacing of 8, the highest VCPU id for the given topology should be: 16 * 8 / 4 =3D 32 and not 16 ... linux,phandle =3D <0x7e7323b8>; interrupt-controller; }; And CPU hot-plug/unplug is broken: (qemu) device_del core1 pseries-hotplug-cpu: Cannot find CPU (drc index 10000004) to remove (qemu) device_del core2 cpu 4 (hwid 8) Ready to die... cpu 5 (hwid 9) Ready to die... cpu 6 (hwid 10) Ready to die... cpu 7 (hwid 11) Ready to die... These are the VCPU ids of core1 actually (qemu) device_add host-spapr-cpu-core,core-id=3D12,id=3Dcore3 (qemu) device_del core3 pseries-hotplug-cpu: Cannot find CPU (drc index 1000000c) to remove This patches all the code in hw/ppc/spapr.c to assume the VSMT spacing when manipulating VCPU ids. Fixes: 8904e5a75005 Signed-off-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9f29434819..ea7429c92a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -160,9 +160,9 @@ static void pre_2_10_vmstate_unregister_dummy_icp(int i) (void *)(uintptr_t) i); } =20 -static inline int xics_max_server_number(void) +static int xics_max_server_number(sPAPRMachineState *spapr) { - return DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(), smp_threads); + return DIV_ROUND_UP(max_cpus * spapr->vsmt, smp_threads); } =20 static void xics_system_init(MachineState *machine, int nr_irqs, Error **e= rrp) @@ -194,7 +194,7 @@ static void xics_system_init(MachineState *machine, int= nr_irqs, Error **errp) if (smc->pre_2_10_has_unused_icps) { int i; =20 - for (i =3D 0; i < xics_max_server_number(); i++) { + for (i =3D 0; i < xics_max_server_number(spapr); i++) { /* Dummy entries get deregistered when real ICPState objects * are registered during CPU core hotplug. */ @@ -337,7 +337,6 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineSt= ate *spapr) int ret =3D 0, offset, cpus_offset; CPUState *cs; char cpu_model[32]; - int smt =3D kvmppc_smt_threads(); uint32_t pft_size_prop[] =3D {0, cpu_to_be32(spapr->htab_shift)}; =20 CPU_FOREACH(cs) { @@ -346,7 +345,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineSt= ate *spapr) int index =3D spapr_vcpu_id(cpu); int compat_smt =3D MIN(smp_threads, ppc_compat_max_vthreads(cpu)); =20 - if ((index % smt) !=3D 0) { + if (index % spapr->vsmt !=3D 0) { continue; } =20 @@ -614,7 +613,6 @@ static void spapr_populate_cpus_dt_node(void *fdt, sPAP= RMachineState *spapr) CPUState *cs; int cpus_offset; char *nodename; - int smt =3D kvmppc_smt_threads(); =20 cpus_offset =3D fdt_add_subnode(fdt, 0, "cpus"); _FDT(cpus_offset); @@ -632,7 +630,7 @@ static void spapr_populate_cpus_dt_node(void *fdt, sPAP= RMachineState *spapr) DeviceClass *dc =3D DEVICE_GET_CLASS(cs); int offset; =20 - if ((index % smt) !=3D 0) { + if (index % spapr->vsmt !=3D 0) { continue; } =20 @@ -1131,7 +1129,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2)); =20 /* /interrupt controller */ - spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP); + spapr_dt_xics(xics_max_server_number(spapr), fdt, PHANDLE_XICP); =20 ret =3D spapr_populate_memory(spapr, fdt); if (ret < 0) { @@ -2224,7 +2222,6 @@ static void spapr_init_cpus(sPAPRMachineState *spapr) MachineState *machine =3D MACHINE(spapr); MachineClass *mc =3D MACHINE_GET_CLASS(machine); const char *type =3D spapr_get_cpu_core_type(machine->cpu_type); - int smt =3D kvmppc_smt_threads(); const CPUArchIdList *possible_cpus; int boot_cores_nr =3D smp_cpus / smp_threads; int i; @@ -2254,7 +2251,7 @@ static void spapr_init_cpus(sPAPRMachineState *spapr) =20 if (mc->has_hotpluggable_cpus) { spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_CPU, - (core_id / smp_threads) * smt); + (core_id / smp_threads) * spapr->vsmt); } =20 if (i < boot_cores_nr) { @@ -3281,10 +3278,10 @@ static void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *d= ev, Error **errp) { + sPAPRMachineState *spapr =3D SPAPR_MACHINE(OBJECT(hotplug_dev)); int index; sPAPRDRConnector *drc; CPUCore *cc =3D CPU_CORE(dev); - int smt =3D kvmppc_smt_threads(); =20 if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index)) { error_setg(errp, "Unable to find CPU core with core-id: %d", @@ -3296,7 +3293,7 @@ void spapr_core_unplug_request(HotplugHandler *hotplu= g_dev, DeviceState *dev, return; } =20 - drc =3D spapr_drc_by_id(TYPE_SPAPR_DRC_CPU, index * smt); + drc =3D spapr_drc_by_id(TYPE_SPAPR_DRC_CPU, index * spapr->vsmt); g_assert(drc); =20 spapr_drc_detach(drc); @@ -3315,7 +3312,6 @@ static void spapr_core_plug(HotplugHandler *hotplug_d= ev, DeviceState *dev, CPUState *cs =3D CPU(core->threads[0]); sPAPRDRConnector *drc; Error *local_err =3D NULL; - int smt =3D kvmppc_smt_threads(); CPUArchId *core_slot; int index; bool hotplugged =3D spapr_drc_hotplugged(dev); @@ -3326,7 +3322,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_d= ev, DeviceState *dev, cc->core_id); return; } - drc =3D spapr_drc_by_id(TYPE_SPAPR_DRC_CPU, index * smt); + drc =3D spapr_drc_by_id(TYPE_SPAPR_DRC_CPU, index * spapr->vsmt); =20 g_assert(drc || !mc->has_hotpluggable_cpus); =20 --=20 2.14.3