@@ -44,6 +44,8 @@ typedef struct AccelClass {
hwaddr start_addr, hwaddr size);
#endif
bool (*cpu_common_realize_unassigned)(CPUState *cpu, Error **errp);
+ bool (*cpu_common_realize_assigned)(CPUState *cpu, Error **errp);
+ void (*cpu_common_unrealize_assigned)(CPUState *cpu);
void (*cpu_common_unrealize_unassigned)(CPUState *cpu);
/* gdbstub related hooks */
@@ -100,6 +102,24 @@ void accel_cpu_instance_init(CPUState *cpu);
*/
bool accel_cpu_common_realize_unassigned(CPUState *cpu, Error **errp);
+/**
+ * accel_cpu_common_realize_assigned:
+ * @cpu: The CPU that needs to call accel-specific cpu realization.
+ * @errp: currently unused.
+ *
+ * The @cpu index is assigned, @cpu is added to the global #cpus_queue.
+ */
+bool accel_cpu_common_realize_assigned(CPUState *cpu, Error **errp);
+
+/**
+ * accel_cpu_common_unrealize_unassigned:
+ * @cpu: The CPU that needs to call accel-specific cpu unrealization.
+ *
+ * The @cpu index is still assigned, @cpu is still part of the global
+ * #cpus_queue.
+ */
+void accel_cpu_common_unrealize_assigned(CPUState *cpu);
+
/**
* accel_cpu_common_unrealize_unassigned:
* @cpu: The CPU that needs to call accel-specific cpu unrealization.
@@ -140,6 +140,29 @@ bool accel_cpu_common_realize_unassigned(CPUState *cpu, Error **errp)
return true;
}
+bool accel_cpu_common_realize_assigned(CPUState *cpu, Error **errp)
+{
+ AccelState *accel = current_accel();
+ AccelClass *acc = ACCEL_GET_CLASS(accel);
+
+ if (acc->cpu_common_realize_assigned
+ && !acc->cpu_common_realize_assigned(cpu, errp)) {
+ return false;
+ }
+
+ return true;
+}
+
+void accel_cpu_common_unrealize_assigned(CPUState *cpu)
+{
+ AccelState *accel = current_accel();
+ AccelClass *acc = ACCEL_GET_CLASS(accel);
+
+ if (acc->cpu_common_unrealize_assigned) {
+ acc->cpu_common_unrealize_assigned(cpu);
+ }
+}
+
void accel_cpu_common_unrealize_unassigned(CPUState *cpu)
{
AccelState *accel = current_accel();
@@ -143,6 +143,10 @@ bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
/* Wait until cpu initialization complete before exposing cpu. */
cpu_list_add(cpu);
+ if (!accel_cpu_common_realize_assigned(cpu, errp)) {
+ return false;
+ }
+
#ifdef CONFIG_USER_ONLY
assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
qdev_get_vmsd(DEVICE(cpu))->unmigratable);
@@ -171,6 +175,8 @@ void cpu_exec_unrealizefn(CPUState *cpu)
}
#endif
+ accel_cpu_common_unrealize_assigned(cpu);
+
cpu_list_remove(cpu);
/*
* Now that the vCPU has been removed from the RCU list, we can call
Introduce handlers called while the vCPU has an assigned index and is still in the global %cpus_queue. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> --- include/qemu/accel.h | 20 ++++++++++++++++++++ accel/accel-target.c | 23 +++++++++++++++++++++++ cpu-target.c | 6 ++++++ 3 files changed, 49 insertions(+)