From nobody Sat Sep 28 22:40:38 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548700991841838.7379169873841; Mon, 28 Jan 2019 10:43:11 -0800 (PST) Received: from localhost ([127.0.0.1]:36836 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goBsE-0003ic-KQ for importer@patchew.org; Mon, 28 Jan 2019 13:43:10 -0500 Received: from eggs.gnu.org ([209.51.188.92]:41238) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goBNe-0003AX-Oi for qemu-devel@nongnu.org; Mon, 28 Jan 2019 13:11:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1goBNc-0000Y4-DX for qemu-devel@nongnu.org; Mon, 28 Jan 2019 13:11:34 -0500 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]:53993) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1goBNc-0000QW-5F for qemu-devel@nongnu.org; Mon, 28 Jan 2019 13:11:32 -0500 Received: by mail-wm1-x333.google.com with SMTP id d15so15040831wmb.3 for ; Mon, 28 Jan 2019 10:11:21 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id b18sm97910681wrw.83.2019.01.28.10.11.18 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 28 Jan 2019 10:11:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=oRVjJfEtFzX/5cZWSR/FAOkkZFICB7IbKExbJeRsgog=; b=XvhjrMa1FJe/+qbEgRcJBBHjc6kNQ5OSWEFi2DXMVzcUQg+bABI6NTsgGj0lbYUeih r4wnI4wxV/jvIIfbLNjQARkf5RLxfbAdLcbK4/dvUVpF1y+s/90uRGcj47wqDkw4t79r RyIXLt7Z/2xyY7Hj7iYkvYxPDnT1cTsic2quA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oRVjJfEtFzX/5cZWSR/FAOkkZFICB7IbKExbJeRsgog=; b=q/tjn4vabo3BwEfQ7ckujAvmbbrpccRq/eXUexxzV2IfGASYBkxzsERL2YiRcmfdDT bhaKtLYvJGenh4cYrPVaqG7CQbrLITAs/89mhfWZYy4Rd+zXTHCzyXdYGx9ZdZaCnzHg e4qtkGlWzIUucW2KpCj0o01eGE/YqVL8lRL4+7I21BeFaIw/YlxQyMeYUE+rBi81+0KO S14oaXQkDTMjMzo4015AsgElFjstnm0YqnrKUnPph+0VtB8jth1mU3y/YzN6MiV/DgiZ vViPhcP69PCwWTPjpcYfFsDGrBBV31fA62b2lVRxNKTEGLPgAjdqS5Km1y1UCgCkF8xz 9+aw== X-Gm-Message-State: AJcUukcGP9sVG6eJ1RP9RnSDE9+YFo617e+2rzDaLeLfhuuIOqsdJ1Q7 rpM5KHYz5k7NDpcjZ3nH9L7cPrwHmtVG6A== X-Google-Smtp-Source: ALg8bN6+pboZFIVv1F/LikEfvbK25MgEsZawzy1/r8uJa8BCQDXjEi2kEXZpNoauNkT/sbbxXje/+A== X-Received: by 2002:a1c:c303:: with SMTP id t3mr16945574wmf.94.1548699080198; Mon, 28 Jan 2019 10:11:20 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 28 Jan 2019 18:10:45 +0000 Message-Id: <20190128181047.20781-25-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190128181047.20781-1-peter.maydell@linaro.org> References: <20190128181047.20781-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::333 Subject: [Qemu-devel] [PULL 24/26] qom/cpu: Add cluster_index to CPUState 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" For TCG we want to distinguish which cluster a CPU is in, and we need to do it quickly. Cache the cluster index in the CPUState struct, by having the cluster object set cpu->cluster_index for each CPU child when it is realized. This means that board/SoC code must add all CPUs to the cluster before realizing the cluster object. Regrettably QOM provides no way to prevent adding children to a realized object and no way for the parent to be notified when a new child is added to it, so we don't have any way to enforce/assert this constraint; all we can do is document it in a comment. We can at least put in a check that the cluster contains at least one CPU, which should catch the typical cases of "realized cluster too early" or "forgot to parent the CPUs into it". The restriction on how many clusters can exist in the system is imposed by TCG code which will be added in a subsequent commit, but the check to enforce it in cluster.c fits better in this one. Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Reviewed-by: Alistair Francis Message-id: 20190121152218.9592-3-peter.maydell@linaro.org --- include/hw/cpu/cluster.h | 24 +++++++++++++++++++++ include/qom/cpu.h | 7 ++++++ hw/cpu/cluster.c | 46 ++++++++++++++++++++++++++++++++++++++++ qom/cpu.c | 1 + 4 files changed, 78 insertions(+) diff --git a/include/hw/cpu/cluster.h b/include/hw/cpu/cluster.h index 73818232437..549c2d31d43 100644 --- a/include/hw/cpu/cluster.h +++ b/include/hw/cpu/cluster.h @@ -34,12 +34,36 @@ * Arm big.LITTLE system) they should be in different clusters. If the CPU= s do * not have the same view of memory (for example the main CPU and a manage= ment * controller processor) they should be in different clusters. + * + * A cluster is created by creating an object of TYPE_CPU_CLUSTER, and then + * adding the CPUs to it as QOM child objects (e.g. using the + * object_initialize_child() or object_property_add_child() functions). + * The CPUs may be either direct children of the cluster object, or indire= ct + * children (e.g. children of children of the cluster object). + * + * All CPUs must be added as children before the cluster is realized. + * (Regrettably QOM provides no way to prevent adding children to a realiz= ed + * object and no way for the parent to be notified when a new child is add= ed + * to it, so this restriction is not checked for, but the system will not + * behave correctly if it is not adhered to. The cluster will assert that + * it contains at least one CPU, which should catch most inadvertent + * violations of this constraint.) + * + * A CPU which is not put into any cluster will be considered implicitly + * to be in a cluster with all the other "loose" CPUs, so all CPUs that are + * not assigned to clusters must be identical. */ =20 #define TYPE_CPU_CLUSTER "cpu-cluster" #define CPU_CLUSTER(obj) \ OBJECT_CHECK(CPUClusterState, (obj), TYPE_CPU_CLUSTER) =20 +/* + * This limit is imposed by TCG, which puts the cluster ID into an + * 8 bit field (and uses all-1s for the default "not in any cluster"). + */ +#define MAX_CLUSTERS 255 + /** * CPUClusterState: * @cluster_id: The cluster ID. This value is for internal use only and sh= ould diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 16bbed1ae09..4c2feb9c17b 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -280,6 +280,11 @@ struct qemu_work_item; /** * CPUState: * @cpu_index: CPU index (informative). + * @cluster_index: Identifies which cluster this CPU is in. + * For boards which don't define clusters or for "loose" CPUs not assign= ed + * to a cluster this will be UNASSIGNED_CLUSTER_INDEX; otherwise it will + * be the same as the cluster-id property of the CPU object's TYPE_CPU_C= LUSTER + * QOM parent. * @nr_cores: Number of cores within this CPU package. * @nr_threads: Number of threads within this CPU. * @running: #true if CPU is currently running (lockless). @@ -405,6 +410,7 @@ struct CPUState { =20 /* TODO Move common fields from CPUArchState here. */ int cpu_index; + int cluster_index; uint32_t halted; uint32_t can_do_io; int32_t exception_index; @@ -1111,5 +1117,6 @@ extern const struct VMStateDescription vmstate_cpu_co= mmon; #endif /* NEED_CPU_H */ =20 #define UNASSIGNED_CPU_INDEX -1 +#define UNASSIGNED_CLUSTER_INDEX -1 =20 #endif diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c index 9d50a235d5c..25f90702b16 100644 --- a/hw/cpu/cluster.c +++ b/hw/cpu/cluster.c @@ -20,19 +20,65 @@ =20 #include "qemu/osdep.h" #include "hw/cpu/cluster.h" +#include "qom/cpu.h" #include "qapi/error.h" #include "qemu/module.h" +#include "qemu/cutils.h" =20 static Property cpu_cluster_properties[] =3D { DEFINE_PROP_UINT32("cluster-id", CPUClusterState, cluster_id, 0), DEFINE_PROP_END_OF_LIST() }; =20 +typedef struct CallbackData { + CPUClusterState *cluster; + int cpu_count; +} CallbackData; + +static int add_cpu_to_cluster(Object *obj, void *opaque) +{ + CallbackData *cbdata =3D opaque; + CPUState *cpu =3D (CPUState *)object_dynamic_cast(obj, TYPE_CPU); + + if (cpu) { + cpu->cluster_index =3D cbdata->cluster->cluster_id; + cbdata->cpu_count++; + } + return 0; +} + +static void cpu_cluster_realize(DeviceState *dev, Error **errp) +{ + /* Iterate through all our CPU children and set their cluster_index */ + CPUClusterState *cluster =3D CPU_CLUSTER(dev); + Object *cluster_obj =3D OBJECT(dev); + CallbackData cbdata =3D { + .cluster =3D cluster, + .cpu_count =3D 0, + }; + + if (cluster->cluster_id >=3D MAX_CLUSTERS) { + error_setg(errp, "cluster-id must be less than %d", MAX_CLUSTERS); + return; + } + + object_child_foreach_recursive(cluster_obj, add_cpu_to_cluster, &cbdat= a); + + /* + * A cluster with no CPUs is a bug in the board/SoC code that created = it; + * if you hit this during development of new code, check that you have + * created the CPUs and parented them into the cluster object before + * realizing the cluster object. + */ + assert(cbdata.cpu_count > 0); +} + static void cpu_cluster_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); =20 dc->props =3D cpu_cluster_properties; + dc->realize =3D cpu_cluster_realize; } =20 static const TypeInfo cpu_cluster_type_info =3D { diff --git a/qom/cpu.c b/qom/cpu.c index 5442a7323be..f5579b1cd50 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -364,6 +364,7 @@ static void cpu_common_initfn(Object *obj) CPUClass *cc =3D CPU_GET_CLASS(obj); =20 cpu->cpu_index =3D UNASSIGNED_CPU_INDEX; + cpu->cluster_index =3D UNASSIGNED_CLUSTER_INDEX; cpu->gdb_num_regs =3D cpu->gdb_num_g_regs =3D cc->gdb_num_core_regs; /* *-user doesn't have configurable SMP topology */ /* the default value is changed by qemu_init_vcpu() for softmmu */ --=20 2.20.1