From: Zhao Liu <zhao1.liu@intel.com>
Currenltly cpu-cluster is used in TCG case to organize CPUs with the
same type.
Wrap 2 things into TCG specific areas:
1. cluster-id:
The cluster-id in TCG case is global, since no higher topology
container above cluster. To simplify the logic of cluster topology
in virtualization, move the cluster-id into CONFIG_TCG, then it
won't be exposed in cli.
2. CPU collection in realize():
In TCG case, the CPUs are added into cluster directly via child<>
property. But in virtualization case, the CPU topology will be built
via topology tree. Thus, wrap CPU collection as the TCG operation.
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
hw/cpu/cluster.c | 30 +++++++++++++++++++++++++-----
include/hw/cpu/cluster.h | 22 ++++++++++++++++++++--
2 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c
index fd978a543e40..340cfad9f8f1 100644
--- a/hw/cpu/cluster.c
+++ b/hw/cpu/cluster.c
@@ -26,7 +26,9 @@
#include "qapi/error.h"
static Property cpu_cluster_properties[] = {
+#ifdef CONFIG_TCG
DEFINE_PROP_UINT32("cluster-id", CPUCluster, cluster_id, 0),
+#endif
DEFINE_PROP_END_OF_LIST()
};
@@ -47,18 +49,17 @@ static int add_cpu_to_cluster(Object *obj, void *opaque)
return 0;
}
-static void cpu_cluster_realize(DeviceState *dev, Error **errp)
+static void cpu_cluster_common_collect_cpus(CPUCluster *cluster, Error **errp)
{
/* Iterate through all our CPU children and set their cluster_index */
- CPUCluster *cluster = CPU_CLUSTER(dev);
- Object *cluster_obj = OBJECT(dev);
+ Object *cluster_obj = OBJECT(cluster);
CallbackData cbdata = {
.cluster = cluster,
.cpu_count = 0,
};
- if (cluster->cluster_id >= MAX_CLUSTERS) {
- error_setg(errp, "cluster-id must be less than %d", MAX_CLUSTERS);
+ if (cluster->cluster_id >= MAX_TCG_CLUSTERS) {
+ error_setg(errp, "cluster-id must be less than %d", MAX_TCG_CLUSTERS);
return;
}
@@ -73,15 +74,34 @@ static void cpu_cluster_realize(DeviceState *dev, Error **errp)
assert(cbdata.cpu_count > 0);
}
+static const struct TCGClusterOps common_cluster_tcg_ops = {
+ .collect_cpus = cpu_cluster_common_collect_cpus,
+};
+
+static void cpu_cluster_realize(DeviceState *dev, Error **errp)
+{
+ CPUCluster *cluster = CPU_CLUSTER(dev);
+ CPUClusterClass *cc = CPU_CLUSTER_GET_CLASS(dev);
+
+ if (cc->tcg_clu_ops->collect_cpus) {
+ cc->tcg_clu_ops->collect_cpus(cluster, errp);
+ }
+}
+
static void cpu_cluster_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ CPUClusterClass *cc = CPU_CLUSTER_CLASS(klass);
device_class_set_props(dc, cpu_cluster_properties);
dc->realize = cpu_cluster_realize;
/* This is not directly for users, CPU children must be attached by code */
dc->user_creatable = false;
+
+#ifdef CONFIG_TCG
+ cc->tcg_clu_ops = &common_cluster_tcg_ops;
+#endif
}
static const TypeInfo cpu_cluster_type_info = {
diff --git a/include/hw/cpu/cluster.h b/include/hw/cpu/cluster.h
index 644b87350268..c038f05ddc9f 100644
--- a/include/hw/cpu/cluster.h
+++ b/include/hw/cpu/cluster.h
@@ -55,13 +55,31 @@
*/
#define TYPE_CPU_CLUSTER "cpu-cluster"
-OBJECT_DECLARE_SIMPLE_TYPE(CPUCluster, CPU_CLUSTER)
+OBJECT_DECLARE_TYPE(CPUCluster, CPUClusterClass, CPU_CLUSTER)
/*
* 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
+#define MAX_TCG_CLUSTERS 255
+
+struct TCGClusterOps {
+ /**
+ * @collect_cpus: Iterate children CPUs and set cluser_index.
+ *
+ * Called when the cluster is realized.
+ */
+ void (*collect_cpus)(CPUCluster *cluster, Error **errp);
+};
+
+struct CPUClusterClass {
+ /*< private >*/
+ DeviceClass parent_class;
+
+ /*< public >*/
+ /* when TCG is not available, this pointer is NULL */
+ const struct TCGClusterOps *tcg_clu_ops;
+};
/**
* CPUCluster:
--
2.34.1