reset: allow registering handlers that aren't called by snapshot loading
Snapshot loading only expects to call deterministic handlers, not non-deterministic ones. So introduce a way of registering handlers that won't be called when reseting for snapshots. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Message-id: 20221025004327.568476-2-Jason@zx2c4.com [PMM: updated json doc comment with Markus' text; fixed checkpatch style nit] Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
c8d6c286ab
commit
7966d70f6f
@ -1356,12 +1356,12 @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
|
|||||||
aspeed_soc_num_cpus(amc->soc_name);
|
aspeed_soc_num_cpus(amc->soc_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fby35_reset(MachineState *state)
|
static void fby35_reset(MachineState *state, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
AspeedMachineState *bmc = ASPEED_MACHINE(state);
|
AspeedMachineState *bmc = ASPEED_MACHINE(state);
|
||||||
AspeedGPIOState *gpio = &bmc->soc.gpio;
|
AspeedGPIOState *gpio = &bmc->soc.gpio;
|
||||||
|
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
|
|
||||||
/* Board ID: 7 (Class-1, 4 slots) */
|
/* Board ID: 7 (Class-1, 4 slots) */
|
||||||
object_property_set_bool(OBJECT(gpio), "gpioV4", true, &error_fatal);
|
object_property_set_bool(OBJECT(gpio), "gpioV4", true, &error_fatal);
|
||||||
|
@ -1239,7 +1239,7 @@ static void mps2_set_remap(Object *obj, const char *value, Error **errp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mps2_machine_reset(MachineState *machine)
|
static void mps2_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
|
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
|
||||||
|
|
||||||
@ -1249,7 +1249,7 @@ static void mps2_machine_reset(MachineState *machine)
|
|||||||
* reset see the correct mapping.
|
* reset see the correct mapping.
|
||||||
*/
|
*/
|
||||||
remap_memory(mms, mms->remap);
|
remap_memory(mms, mms->remap);
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mps2tz_class_init(ObjectClass *oc, void *data)
|
static void mps2tz_class_init(ObjectClass *oc, void *data)
|
||||||
|
@ -33,6 +33,7 @@ typedef struct QEMUResetEntry {
|
|||||||
QTAILQ_ENTRY(QEMUResetEntry) entry;
|
QTAILQ_ENTRY(QEMUResetEntry) entry;
|
||||||
QEMUResetHandler *func;
|
QEMUResetHandler *func;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
|
bool skip_on_snapshot_load;
|
||||||
} QEMUResetEntry;
|
} QEMUResetEntry;
|
||||||
|
|
||||||
static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers =
|
static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers =
|
||||||
@ -47,6 +48,16 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque)
|
|||||||
QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
|
QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque)
|
||||||
|
{
|
||||||
|
QEMUResetEntry *re = g_new0(QEMUResetEntry, 1);
|
||||||
|
|
||||||
|
re->func = func;
|
||||||
|
re->opaque = opaque;
|
||||||
|
re->skip_on_snapshot_load = true;
|
||||||
|
QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
|
||||||
|
}
|
||||||
|
|
||||||
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
|
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
|
||||||
{
|
{
|
||||||
QEMUResetEntry *re;
|
QEMUResetEntry *re;
|
||||||
@ -60,12 +71,16 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_devices_reset(void)
|
void qemu_devices_reset(ShutdownCause reason)
|
||||||
{
|
{
|
||||||
QEMUResetEntry *re, *nre;
|
QEMUResetEntry *re, *nre;
|
||||||
|
|
||||||
/* reset all devices */
|
/* reset all devices */
|
||||||
QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
|
QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
|
||||||
|
if (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
|
||||||
|
re->skip_on_snapshot_load) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
re->func(re->opaque);
|
re->func(re->opaque);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,12 +411,12 @@ static void machine_hppa_init(MachineState *machine)
|
|||||||
cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
|
cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hppa_machine_reset(MachineState *ms)
|
static void hppa_machine_reset(MachineState *ms, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
unsigned int smp_cpus = ms->smp.cpus;
|
unsigned int smp_cpus = ms->smp.cpus;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
|
|
||||||
/* Start all CPUs at the firmware entry point.
|
/* Start all CPUs at the firmware entry point.
|
||||||
* Monarch CPU will initialize firmware, secondary CPUs
|
* Monarch CPU will initialize firmware, secondary CPUs
|
||||||
|
@ -467,7 +467,7 @@ static void microvm_machine_state_init(MachineState *machine)
|
|||||||
microvm_devices_init(mms);
|
microvm_devices_init(mms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void microvm_machine_reset(MachineState *machine)
|
static void microvm_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
MicrovmMachineState *mms = MICROVM_MACHINE(machine);
|
MicrovmMachineState *mms = MICROVM_MACHINE(machine);
|
||||||
CPUState *cs;
|
CPUState *cs;
|
||||||
@ -480,7 +480,7 @@ static void microvm_machine_reset(MachineState *machine)
|
|||||||
mms->kernel_cmdline_fixed = true;
|
mms->kernel_cmdline_fixed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
|
|
||||||
CPU_FOREACH(cs) {
|
CPU_FOREACH(cs) {
|
||||||
cpu = X86_CPU(cs);
|
cpu = X86_CPU(cs);
|
||||||
|
@ -1847,12 +1847,12 @@ static void pc_machine_initfn(Object *obj)
|
|||||||
cxl_machine_init(obj, &pcms->cxl_devices_state);
|
cxl_machine_init(obj, &pcms->cxl_devices_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pc_machine_reset(MachineState *machine)
|
static void pc_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
CPUState *cs;
|
CPUState *cs;
|
||||||
X86CPU *cpu;
|
X86CPU *cpu;
|
||||||
|
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
|
|
||||||
/* Reset APIC after devices have been reset to cancel
|
/* Reset APIC after devices have been reset to cancel
|
||||||
* any changes that qemu_devices_reset() might have done.
|
* any changes that qemu_devices_reset() might have done.
|
||||||
@ -1867,7 +1867,7 @@ static void pc_machine_reset(MachineState *machine)
|
|||||||
static void pc_machine_wakeup(MachineState *machine)
|
static void pc_machine_wakeup(MachineState *machine)
|
||||||
{
|
{
|
||||||
cpu_synchronize_all_states();
|
cpu_synchronize_all_states();
|
||||||
pc_machine_reset(machine);
|
pc_machine_reset(machine, SHUTDOWN_CAUSE_NONE);
|
||||||
cpu_synchronize_all_post_reset();
|
cpu_synchronize_all_post_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,14 +248,14 @@ static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
|
|||||||
pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
|
pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pegasos2_machine_reset(MachineState *machine)
|
static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
|
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
|
||||||
void *fdt;
|
void *fdt;
|
||||||
uint64_t d[2];
|
uint64_t d[2];
|
||||||
int sz;
|
int sz;
|
||||||
|
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
if (!pm->vof) {
|
if (!pm->vof) {
|
||||||
return; /* Firmware should set up machine so nothing to do */
|
return; /* Firmware should set up machine so nothing to do */
|
||||||
}
|
}
|
||||||
|
@ -643,13 +643,13 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pnv_reset(MachineState *machine)
|
static void pnv_reset(MachineState *machine, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
PnvMachineState *pnv = PNV_MACHINE(machine);
|
PnvMachineState *pnv = PNV_MACHINE(machine);
|
||||||
IPMIBmc *bmc;
|
IPMIBmc *bmc;
|
||||||
void *fdt;
|
void *fdt;
|
||||||
|
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The machine should provide by default an internal BMC simulator.
|
* The machine should provide by default an internal BMC simulator.
|
||||||
|
@ -1623,7 +1623,7 @@ void spapr_check_mmu_mode(bool guest_radix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spapr_machine_reset(MachineState *machine)
|
static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
SpaprMachineState *spapr = SPAPR_MACHINE(machine);
|
SpaprMachineState *spapr = SPAPR_MACHINE(machine);
|
||||||
PowerPCCPU *first_ppc_cpu;
|
PowerPCCPU *first_ppc_cpu;
|
||||||
@ -1649,7 +1649,7 @@ static void spapr_machine_reset(MachineState *machine)
|
|||||||
spapr_setup_hpt(spapr);
|
spapr_setup_hpt(spapr);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
|
|
||||||
spapr_ovec_cleanup(spapr->ov5_cas);
|
spapr_ovec_cleanup(spapr->ov5_cas);
|
||||||
spapr->ov5_cas = spapr_ovec_new();
|
spapr->ov5_cas = spapr_ovec_new();
|
||||||
|
@ -411,7 +411,7 @@ static void s390_pv_prepare_reset(S390CcwMachineState *ms)
|
|||||||
s390_pv_prep_reset();
|
s390_pv_prep_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void s390_machine_reset(MachineState *machine)
|
static void s390_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||||
{
|
{
|
||||||
S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
|
S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
|
||||||
enum s390_reset reset_type;
|
enum s390_reset reset_type;
|
||||||
@ -433,7 +433,7 @@ static void s390_machine_reset(MachineState *machine)
|
|||||||
s390_machine_unprotect(ms);
|
s390_machine_unprotect(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
s390_crypto_reset();
|
s390_crypto_reset();
|
||||||
|
|
||||||
/* configure and start the ipl CPU only */
|
/* configure and start the ipl CPU only */
|
||||||
|
@ -231,7 +231,7 @@ struct MachineClass {
|
|||||||
const char *deprecation_reason;
|
const char *deprecation_reason;
|
||||||
|
|
||||||
void (*init)(MachineState *state);
|
void (*init)(MachineState *state);
|
||||||
void (*reset)(MachineState *state);
|
void (*reset)(MachineState *state, ShutdownCause reason);
|
||||||
void (*wakeup)(MachineState *state);
|
void (*wakeup)(MachineState *state);
|
||||||
int (*kvm_type)(MachineState *machine, const char *arg);
|
int (*kvm_type)(MachineState *machine, const char *arg);
|
||||||
|
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
#ifndef QEMU_SYSEMU_RESET_H
|
#ifndef QEMU_SYSEMU_RESET_H
|
||||||
#define QEMU_SYSEMU_RESET_H
|
#define QEMU_SYSEMU_RESET_H
|
||||||
|
|
||||||
|
#include "qapi/qapi-events-run-state.h"
|
||||||
|
|
||||||
typedef void QEMUResetHandler(void *opaque);
|
typedef void QEMUResetHandler(void *opaque);
|
||||||
|
|
||||||
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
|
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
|
||||||
|
void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque);
|
||||||
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
|
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
|
||||||
void qemu_devices_reset(void);
|
void qemu_devices_reset(ShutdownCause reason);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3058,7 +3058,7 @@ bool load_snapshot(const char *name, const char *vmstate,
|
|||||||
goto err_drain;
|
goto err_drain;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_system_reset(SHUTDOWN_CAUSE_NONE);
|
qemu_system_reset(SHUTDOWN_CAUSE_SNAPSHOT_LOAD);
|
||||||
mis->from_src_file = f;
|
mis->from_src_file = f;
|
||||||
|
|
||||||
if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) {
|
if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) {
|
||||||
|
@ -86,12 +86,16 @@
|
|||||||
# ignores --no-reboot. This is useful for sanitizing
|
# ignores --no-reboot. This is useful for sanitizing
|
||||||
# hypercalls on s390 that are used during kexec/kdump/boot
|
# hypercalls on s390 that are used during kexec/kdump/boot
|
||||||
#
|
#
|
||||||
|
# @snapshot-load: A snapshot is being loaded by the record & replay
|
||||||
|
# subsystem. This value is used only within QEMU. It
|
||||||
|
# doesn't occur in QMP. (since 7.2)
|
||||||
|
#
|
||||||
##
|
##
|
||||||
{ 'enum': 'ShutdownCause',
|
{ 'enum': 'ShutdownCause',
|
||||||
# Beware, shutdown_caused_by_guest() depends on enumeration order
|
# Beware, shutdown_caused_by_guest() depends on enumeration order
|
||||||
'data': [ 'none', 'host-error', 'host-qmp-quit', 'host-qmp-system-reset',
|
'data': [ 'none', 'host-error', 'host-qmp-quit', 'host-qmp-system-reset',
|
||||||
'host-signal', 'host-ui', 'guest-shutdown', 'guest-reset',
|
'host-signal', 'host-ui', 'guest-shutdown', 'guest-reset',
|
||||||
'guest-panic', 'subsystem-reset'] }
|
'guest-panic', 'subsystem-reset', 'snapshot-load'] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @StatusInfo:
|
# @StatusInfo:
|
||||||
|
@ -441,11 +441,16 @@ void qemu_system_reset(ShutdownCause reason)
|
|||||||
cpu_synchronize_all_states();
|
cpu_synchronize_all_states();
|
||||||
|
|
||||||
if (mc && mc->reset) {
|
if (mc && mc->reset) {
|
||||||
mc->reset(current_machine);
|
mc->reset(current_machine, reason);
|
||||||
} else {
|
} else {
|
||||||
qemu_devices_reset();
|
qemu_devices_reset(reason);
|
||||||
}
|
}
|
||||||
if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
|
switch (reason) {
|
||||||
|
case SHUTDOWN_CAUSE_NONE:
|
||||||
|
case SHUTDOWN_CAUSE_SUBSYSTEM_RESET:
|
||||||
|
case SHUTDOWN_CAUSE_SNAPSHOT_LOAD:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
|
qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
|
||||||
}
|
}
|
||||||
cpu_synchronize_all_post_reset();
|
cpu_synchronize_all_post_reset();
|
||||||
|
Loading…
Reference in New Issue
Block a user