We can not retrieve target list when do call to 
module_call_init(MODULE_INIT_QOM)
But in future, we need iterate target list inside type_init referenced 
functions for
generate all QOM variants depends on target list(without select the target).
So we have to prepare the QOM target list before 
module_call_init(MODULE_INIT_QOM)

Signed-off-by: Yonggang Luo <[email protected]>
---
 include/qemu/target-info-qom.h |  4 ++++
 system/vl.c                    |  2 +-
 target-info-qom.c              | 26 +++++++++++++++++++++++++-
 tests/qtest/fuzz/fuzz.c        |  2 +-
 tests/unit/test-multi-target.c | 20 +++++++++++++-------
 5 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h
index ba2e4370afb..031d9ce32a5 100644
--- a/include/qemu/target-info-qom.h
+++ b/include/qemu/target-info-qom.h
@@ -25,6 +25,10 @@ typedef struct TargetInfoQomClass {
 
 OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO)
 
+/* Initialize before MODULE_INIT_QOM; cache is owned by this module. */
+void target_info_qom_init(void);
+GSList *target_info_qom_get_targets(void);
+
 void target_info_qom_set_target(void);
 void target_info_qom_set_target_info(const TargetInfo *ti);
 
diff --git a/system/vl.c b/system/vl.c
index fbe580746d3..a7684abdd3a 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2914,7 +2914,7 @@ void qemu_init(int argc, char **argv)
 
     os_setup_limits();
 
-    module_call_init(MODULE_INIT_TARGET_INFO);
+    target_info_qom_init();
     target_info_qom_set_target();
 
     module_init_info(qemu_modinfo);
diff --git a/target-info-qom.c b/target-info-qom.c
index aeeedb7e818..8d3f2b7280b 100644
--- a/target-info-qom.c
+++ b/target-info-qom.c
@@ -8,6 +8,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qemu/module.h"
 #include "qom/object.h"
 #include "qemu/target-info-def.h"
 #include "qemu/target-info-init.h"
@@ -34,6 +35,29 @@ static const TypeInfo target_info_parent_type = {
 DEFINE_TARGET_INFO_TYPE(target_info_parent_type)
 
 static const TargetInfo *target_info_ptr;
+static GSList *target_info_classes;
+static bool target_info_initialized;
+
+void target_info_qom_init(void)
+{
+    if (target_info_initialized) {
+        return;
+    }
+
+    module_call_init(MODULE_INIT_TARGET_INFO);
+    /*
+     * Avoid enumerating target-info classes during QOM registration,
+     * which can leave unrelated types incomplete.
+     */
+    target_info_classes = object_class_get_list(TYPE_TARGET_INFO, false);
+    target_info_initialized = true;
+}
+
+GSList *target_info_qom_get_targets(void)
+{
+    assert(target_info_initialized);
+    return target_info_classes;
+}
 
 const TargetInfo *target_info(void)
 {
@@ -42,7 +66,7 @@ const TargetInfo *target_info(void)
 
 void target_info_qom_set_target(void)
 {
-    g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
+    GSList *targets = target_info_qom_get_targets();
 
     size_t num_found = g_slist_length(targets);
     if (num_found != 1) {
diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
index a3a131c80f8..570fc0b45b2 100644
--- a/tests/qtest/fuzz/fuzz.c
+++ b/tests/qtest/fuzz/fuzz.c
@@ -173,7 +173,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char 
***envp)
 
     /* Initialize qgraph and modules */
     qos_graph_init();
-    module_call_init(MODULE_INIT_TARGET_INFO);
+    target_info_qom_init();
     target_info_qom_set_target();
     module_call_init(MODULE_INIT_FUZZ_TARGET);
     module_call_init(MODULE_INIT_QOM);
diff --git a/tests/unit/test-multi-target.c b/tests/unit/test-multi-target.c
index 89b55bb1632..a91fe8e6d07 100644
--- a/tests/unit/test-multi-target.c
+++ b/tests/unit/test-multi-target.c
@@ -30,23 +30,29 @@
 /* stub for system/main.c */
 int (*qemu_main)(void);
 
+static GSList *targets;
+
 static void test_qom_types_are_unique(void)
 {
-    module_call_init(MODULE_INIT_TARGET_INFO);
-    g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
     g_assert(targets);
-    const TargetInfo *first_ti = TARGET_INFO_CLASS(targets->data)->target_info;
-    target_info_qom_set_target_info(first_ti);
-
-    /* register all types */
-    module_call_init(MODULE_INIT_QOM);
     /* trigger type_initialize for all types */
     object_class_get_list("", false);
+
+    g_assert_true(targets == target_info_qom_get_targets());
 }
 
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
+    target_info_qom_init();
+    targets = target_info_qom_get_targets();
+
+    const TargetInfo *first_ti = TARGET_INFO_CLASS(targets->data)->target_info;
+    target_info_qom_set_target_info(first_ti);
+
+    /* register all types */
+    module_call_init(MODULE_INIT_QOM);
+
     g_test_add_func("/multi-targets/qom-types-are-unique",
                    test_qom_types_are_unique);
     return g_test_run();
-- 
2.55.0.windows.3


Reply via email to