For the single-binary, we want to be able to retrieve at runtime the current target among the different ones available. A consequence is that we can't rely on existing target_info() definition since it will create a conflict once more than one target is available.
To solve this, we add TargetInfo in QOM, with this hierarchy. We define one class "target-info-X" per target, that inherits from abstract class "target-info". Using concrete vs abstract class ensure we can easily filter "target-info-X" from all QOM types. Associated TargetInfo is directly set through class initialization, without relying on any instance. For user mode, we simply define target_info() like it was done previously. In this patch, we keep the same definition for system-mode also, and it will be replaced in next commits. We will introduce detection of target from QOM, so we need to make sure those types are registered early. Reviewed-by: Richard Henderson <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Pierrick Bouvier <[email protected]> --- configs/targets/aarch64-softmmu.c | 6 ++-- configs/targets/arm-softmmu.c | 6 ++-- include/qemu/module.h | 1 + include/qemu/target-info-init.h | 58 +++++++++++++++++++++++++++++++ include/qemu/target-info-qom.h | 28 +++++++++++++++ system/vl.c | 2 ++ target-info-qom.c | 24 +++++++++++++ target-info-stub.c | 6 ++-- tests/qtest/fuzz/fuzz.c | 1 + 9 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 include/qemu/target-info-init.h create mode 100644 include/qemu/target-info-qom.h diff --git a/configs/targets/aarch64-softmmu.c b/configs/targets/aarch64-softmmu.c index 82ccb575759..75d95b0e743 100644 --- a/configs/targets/aarch64-softmmu.c +++ b/configs/targets/aarch64-softmmu.c @@ -8,6 +8,7 @@ #include "qemu/osdep.h" #include "qemu/target-info-impl.h" +#include "qemu/target-info-init.h" #include "hw/arm/machines-qom.h" #include "target/arm/cpu-qom.h" #include "target/arm/cpu-param.h" @@ -23,7 +24,4 @@ static const TargetInfo target_info_aarch64_system = { .page_bits_init = TARGET_PAGE_BITS_LEGACY, }; -const TargetInfo *target_info(void) -{ - return &target_info_aarch64_system; -} +target_info_init(target_info_aarch64_system) diff --git a/configs/targets/arm-softmmu.c b/configs/targets/arm-softmmu.c index 18940e51e55..73546fa5737 100644 --- a/configs/targets/arm-softmmu.c +++ b/configs/targets/arm-softmmu.c @@ -8,6 +8,7 @@ #include "qemu/osdep.h" #include "qemu/target-info-impl.h" +#include "qemu/target-info-init.h" #include "hw/arm/machines-qom.h" #include "target/arm/cpu-qom.h" #include "target/arm/cpu-param.h" @@ -23,7 +24,4 @@ static const TargetInfo target_info_arm_system = { .page_bits_init = TARGET_PAGE_BITS_LEGACY, }; -const TargetInfo *target_info(void) -{ - return &target_info_arm_system; -} +target_info_init(target_info_arm_system) diff --git a/include/qemu/module.h b/include/qemu/module.h index 9885ac9afb3..fccf017bf9e 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -43,6 +43,7 @@ typedef enum { MODULE_INIT_MIGRATION, MODULE_INIT_BLOCK, MODULE_INIT_OPTS, + MODULE_INIT_TARGET_INFO, MODULE_INIT_QOM, MODULE_INIT_TRACE, MODULE_INIT_XEN_BACKEND, diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h new file mode 100644 index 00000000000..32c323a7ef9 --- /dev/null +++ b/include/qemu/target-info-init.h @@ -0,0 +1,58 @@ +/* + * QEMU target info initialization + * + * Copyright (c) Qualcomm + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This file is included by each file defining a TargetInfo structure and is + * responsible for registering it. + */ + +#ifndef QEMU_TARGET_INFO_INIT_H +#define QEMU_TARGET_INFO_INIT_H + +#define DEFINE_TARGET_INFO_TYPE(info) \ +static void do_qemu_init_target_info(void) \ +{ \ + type_register_static(&info); \ +} \ +module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO) + +#ifdef COMPILING_PER_TARGET +#ifdef CONFIG_USER_ONLY + +/* + * User mode does not support multiple targets in the same binary, so just + * define target_info(). + */ +#define target_info_init(ti_var) \ +const TargetInfo *target_info(void) \ +{ \ + return &ti_var; \ +} + +#else /* CONFIG_USER_ONLY */ + +#include "qemu/target-info-qom.h" +#include "qom/object.h" + +#define target_info_init(ti_var) \ +const TargetInfo *target_info(void) \ +{ \ + return &ti_var; \ +} \ + \ +static const TypeInfo target_info_qom_target_type_info = { \ + .name = TYPE_TARGET_INFO"-"TARGET_NAME, \ + .parent = TYPE_TARGET_INFO, \ + .instance_size = sizeof(TargetInfoQom), \ + .class_size = sizeof(TargetInfoQomClass), \ + .class_data = &ti_var, \ +}; \ +DEFINE_TARGET_INFO_TYPE(target_info_qom_target_type_info) + +#endif /* CONFIG_USER_ONLY */ +#endif /* COMPILING_PER_TARGET */ + +#endif /* QEMU_TARGET_INFO_INIT_H */ diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h new file mode 100644 index 00000000000..585995c7ad0 --- /dev/null +++ b/include/qemu/target-info-qom.h @@ -0,0 +1,28 @@ +/* + * QEMU target info QOM types + * + * Copyright (c) Qualcomm + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef QEMU_TARGET_INFO_QOM_H +#define QEMU_TARGET_INFO_QOM_H + +#include "qemu/target-info-impl.h" +#include "qom/object.h" + +#define TYPE_TARGET_INFO "target-info" + +typedef struct TargetInfoQom { + Object parent_obj; +} TargetInfoQom; + +typedef struct TargetInfoQomClass { + ObjectClass parent_class; + const TargetInfo *target_info; +} TargetInfoQomClass; + +OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO) + +#endif /* QEMU_TARGET_INFO_QOM_H */ diff --git a/system/vl.c b/system/vl.c index d2f4044e5d8..e44da0941d4 100644 --- a/system/vl.c +++ b/system/vl.c @@ -2889,6 +2889,8 @@ void qemu_init(int argc, char **argv) os_setup_limits(); + module_call_init(MODULE_INIT_TARGET_INFO); + module_init_info(qemu_modinfo); module_allow_arch(target_name()); diff --git a/target-info-qom.c b/target-info-qom.c index 7fd58d24818..79752366b61 100644 --- a/target-info-qom.c +++ b/target-info-qom.c @@ -7,7 +7,11 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qom/object.h" +#include "qemu/target-info-impl.h" +#include "qemu/target-info-init.h" +#include "qemu/target-info-qom.h" #include "hw/arm/machines-qom.h" static const TypeInfo target_info_types[] = { @@ -22,3 +26,23 @@ static const TypeInfo target_info_types[] = { }; DEFINE_TYPES(target_info_types) + +static void target_info_qom_class_init(ObjectClass *oc, const void * data) +{ + TargetInfoQomClass *klass = TARGET_INFO_CLASS(oc); + klass->target_info = data; +} + +static const TypeInfo target_info_parent_type = { + .name = TYPE_TARGET_INFO, + .parent = TYPE_OBJECT, + .instance_size = sizeof(TargetInfoQom), + .class_size = sizeof(TargetInfoQomClass), + /* use class_base_init so children classes can set class_data accordingly */ + .class_base_init = target_info_qom_class_init, + /* children classes will be concrete, which allows to easily query them + * without listing this parent class also */ + .abstract = true, +}; + +DEFINE_TARGET_INFO_TYPE(target_info_parent_type) diff --git a/target-info-stub.c b/target-info-stub.c index 07d8647ed8e..22b7911201c 100644 --- a/target-info-stub.c +++ b/target-info-stub.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "qemu/target-info.h" #include "qemu/target-info-impl.h" +#include "qemu/target-info-init.h" #include "hw/core/boards.h" #include "cpu.h" #include "exec/cpu-defs.h" @@ -41,7 +42,4 @@ static const TargetInfo target_info_stub = { #endif }; -const TargetInfo *target_info(void) -{ - return &target_info_stub; -} +target_info_init(target_info_stub) diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c index d2355989616..de230d20e0f 100644 --- a/tests/qtest/fuzz/fuzz.c +++ b/tests/qtest/fuzz/fuzz.c @@ -172,6 +172,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) /* Initialize qgraph and modules */ qos_graph_init(); + module_call_init(MODULE_INIT_TARGET_INFO); module_call_init(MODULE_INIT_FUZZ_TARGET); module_call_init(MODULE_INIT_QOM); module_call_init(MODULE_INIT_LIBQOS); -- 2.43.0
