diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index cb668703bd..cbb4e3737d 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -216,12 +216,11 @@ static int64_t load_kernel_info(struct
loongarch_boot_info *info)
return kernel_entry;
}
-static void reset_load_elf(void *opaque)
+void reset_load_elf(void *opaque)
{
LoongArchCPU *cpu = opaque;
CPULoongArchState *env = &cpu->env;
- cpu_reset(CPU(cpu));
if (env->load_elf) {
if (cpu == LOONGARCH_CPU(first_cpu)) {
env->gpr[4] = env->boot_info->a0;
@@ -320,12 +319,6 @@ static void loongarch_direct_kernel_boot(struct
loongarch_boot_info *info)
void loongarch_load_kernel(MachineState *ms, struct
loongarch_boot_info *info)
{
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms);
- int i;
-
- /* register reset function */
- for (i = 0; i < ms->smp.cpus; i++) {
- qemu_register_reset(reset_load_elf,
LOONGARCH_CPU(qemu_get_cpu(i)));
- }
info->kernel_filename = ms->kernel_filename;
info->kernel_cmdline = ms->kernel_cmdline;
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 9a635d1d3d..80680d178c 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -1434,6 +1434,19 @@ static int64_t
virt_get_default_cpu_node_id(const MachineState *ms, int idx)
}
}
+static void virt_reset(MachineState *machine, ResetType type)
+{
+ CPUState *cs;
+
+ /* Reset all devices including CPU devices */
+ qemu_devices_reset(type);
+
+ /* Reset PC and register context for kernel direct booting
method */
+ CPU_FOREACH(cs) {
+ reset_load_elf(LOONGARCH_CPU(cs));
+ }
+}
+
static void virt_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -1457,6 +1470,7 @@ static void virt_class_init(ObjectClass *oc,
void *data)
mc->auto_enable_numa_with_memdev = true;
mc->get_hotplug_handler = virt_get_hotplug_handler;
mc->default_nic = "virtio-net-pci";
+ mc->reset = virt_reset;
hc->plug = virt_device_plug_cb;
hc->pre_plug = virt_device_pre_plug;
hc->unplug_request = virt_device_unplug_request;
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index b3b870df1f..c7020ec9bb 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -115,5 +115,6 @@ struct memmap_entry {
};
void loongarch_load_kernel(MachineState *ms, struct
loongarch_boot_info *info);
+void reset_load_elf(void *opaque);
#endif /* HW_LOONGARCH_BOOT_H */
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 7212fb5f8f..f7f8fcc024 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -592,6 +592,13 @@ static void
loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info)
info->print_insn = print_insn_loongarch;
}
+#ifndef CONFIG_USER_ONLY
+static void loongarch_cpu_reset_cb(void *opaque)
+{
+ cpu_reset((CPUState *) opaque);
+}
+#endif
+
static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -607,6 +614,9 @@ static void loongarch_cpu_realizefn(DeviceState
*dev, Error **errp)
loongarch_cpu_register_gdb_regs_for_features(cs);
cpu_reset(cs);
+#ifndef CONFIG_USER_ONLY
+ qemu_register_reset(loongarch_cpu_reset_cb, dev);
+#endif
qemu_init_vcpu(cs);
lacc->parent_realize(dev, errp);
base-commit: 58d49b5895f2e0b5cfe4b2901bf24f3320b74f29