accel/tcg: Complete cpu initialization before registration

Delay cpu_list_add until realize is complete, so that cross-cpu
interaction does not happen with incomplete cpu state.  For this,
we must delay plugin initialization out of tcg_exec_realizefn,
because no cpu_index has been assigned.

Fixes a problem with cross-cpu jump cache flushing, when the
jump cache has not yet been allocated.

Fixes: a976a99a29 ("include/hw/core: Create struct CPUJumpCache")
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reported-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2022-10-31 13:26:36 +11:00
parent 6317933086
commit 4e4fa6c12d
3 changed files with 21 additions and 13 deletions

10
cpu.c
View File

@@ -134,15 +134,23 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
/* cache the cpu class for the hotpath */
cpu->cc = CPU_GET_CLASS(cpu);
cpu_list_add(cpu);
if (!accel_cpu_realizefn(cpu, errp)) {
return;
}
/* NB: errp parameter is unused currently */
if (tcg_enabled()) {
tcg_exec_realizefn(cpu, errp);
}
/* Wait until cpu initialization complete before exposing cpu. */
cpu_list_add(cpu);
/* Plugin initialization must wait until cpu_index assigned. */
if (tcg_enabled()) {
qemu_plugin_vcpu_init_hook(cpu);
}
#ifdef CONFIG_USER_ONLY
assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
qdev_get_vmsd(DEVICE(cpu))->unmigratable);