diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2024-09-26 17:10:39 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2024-09-26 17:10:39 +0100 |
commit | e10cd93872c31332b002c933a798ab0bc51705a4 (patch) | |
tree | f7a27781e950a3ddcbae43efe8058fa5bbc7bb9f | |
parent | a53b931645183bd0c15dd19ae0708fc3c81ecf1d (diff) | |
parent | 78c8f780d3f0d6d17aa93d6f99ff72960080fdd7 (diff) |
Merge tag 'mem-2024-09-24' of https://github.com/davidhildenbrand/qemu into staging
Hi,
"Host Memory Backends" and "Memory devices" queue ("mem"):
- Kconfig fix for virtio-based memory devices
- virtio-mem support for suspend+wake-up with plugged memory
- hostmem fix when specifying "merge=off"
# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEG9nKrXNcTDpGDfzKTd4Q9wD/g1oFAmbyikMRHGRhdmlkQHJl
# ZGhhdC5jb20ACgkQTd4Q9wD/g1q6MBAAitNST73Shc+j327WvRLHQDkzkAlIYm+M
# E8NqtDiV11h7A0eNVu+5BkY/ejtY0Fduae3nxIkrHjK20eHHpiNPUp3hBNIhkKs3
# vlSaU8FLGdt58CteMGcLYsP2E32WNNTckaFGwGjDmyUEfk+Gug4r/rJAZXDfuuLV
# 083I0/MuUF+ozPA0c2MrOwhoBPerg3a5aflVpbgPwGNrT9BHMjo62Q5QzG3U7mxr
# HnlLAScSXsYg2z+d5XLXkKLAiZ4C7UN4vfUAOZwqkfs7IFUTtFO/ev6e7VZI747n
# XhAqOAKzLqPu7tBPZJIC6jwZAUIv5yM0/v5qhVvVVdu7H0ZMtSCXyvCVtnT25Rsn
# yiA+XvCOb7yQ3hRbBIi60IzjNYfWbvw+oTVIDfXkG35TeNf4ZdjWtAiUmw9s5U9Q
# z0tINsD7VlSkbh5h3PkFw1+xagIuJAVkp673HHTtQsg+xgYK2ur5jhhWJdJlnpzA
# 77CAu07UaqU39ssnC2zeGG1eNRA4uzjwQtREzqH2jMfkw/7UuUeXMF+v/fEuLn6w
# JneSMq/a0gmD42HNae0Y40cn2Akfj6+wFu1rW3djF8F6TeLUSssQhbQSHCMwGoOg
# qX7O/3SeSRzlnp3Zyx9Tr7s+BkMz0EGGDe17GQwTQUX2t5wR5iXoGqpKZgOBA8En
# 6uUIcjBUckc=
# =PExj
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 24 Sep 2024 10:45:39 BST
# gpg: using RSA key 1BD9CAAD735C4C3A460DFCCA4DDE10F700FF835A
# gpg: issuer "david@redhat.com"
# gpg: Good signature from "David Hildenbrand <david@redhat.com>" [marginal]
# gpg: aka "David Hildenbrand <davidhildenbrand@gmail.com>" [full]
# gpg: aka "David Hildenbrand <hildenbr@in.tum.de>" [unknown]
# Primary key fingerprint: 1BD9 CAAD 735C 4C3A 460D FCCA 4DDE 10F7 00FF 835A
* tag 'mem-2024-09-24' of https://github.com/davidhildenbrand/qemu:
hostmem: Apply merge property after the memory region is initialized
virtio-mem: Add support for suspend+wake-up with plugged memory
virtio-mem: Use new Resettable framework instead of LegacyReset
reset: Add RESET_TYPE_WAKEUP
reset: Use ResetType for qemu_devices_reset() and MachineClass::reset()
virtio: kconfig: memory devices are PCI only
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | backends/hostmem.c | 2 | ||||
-rw-r--r-- | docs/devel/reset.rst | 12 | ||||
-rw-r--r-- | hw/arm/aspeed.c | 4 | ||||
-rw-r--r-- | hw/arm/mps2-tz.c | 4 | ||||
-rw-r--r-- | hw/core/reset.c | 5 | ||||
-rw-r--r-- | hw/hppa/machine.c | 4 | ||||
-rw-r--r-- | hw/i386/microvm.c | 4 | ||||
-rw-r--r-- | hw/i386/pc.c | 6 | ||||
-rw-r--r-- | hw/ppc/pegasos2.c | 4 | ||||
-rw-r--r-- | hw/ppc/pnv.c | 4 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 6 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 4 | ||||
-rw-r--r-- | hw/virtio/Kconfig | 11 | ||||
-rw-r--r-- | hw/virtio/virtio-mem.c | 48 | ||||
-rw-r--r-- | hw/virtio/virtio-qmp.c | 3 | ||||
-rw-r--r-- | include/hw/boards.h | 3 | ||||
-rw-r--r-- | include/hw/resettable.h | 2 | ||||
-rw-r--r-- | include/hw/virtio/virtio-mem.h | 4 | ||||
-rw-r--r-- | include/sysemu/reset.h | 5 | ||||
-rw-r--r-- | system/runstate.c | 13 |
20 files changed, 103 insertions, 45 deletions
diff --git a/backends/hostmem.c b/backends/hostmem.c index 4e5576a4ad..181446626a 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -178,7 +178,7 @@ static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp) return; } - if (!host_memory_backend_mr_inited(backend) && + if (host_memory_backend_mr_inited(backend) && value != backend->merge) { void *ptr = memory_region_get_ram_ptr(&backend->mr); uint64_t sz = memory_region_size(&backend->mr); diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst index ed41e09f16..74c7c0171a 100644 --- a/docs/devel/reset.rst +++ b/docs/devel/reset.rst @@ -44,6 +44,17 @@ The Resettable interface handles reset types with an enum ``ResetType``: value on each cold reset, such as RNG seed information, and which they must not reinitialize on a snapshot-load reset. +``RESET_TYPE_WAKEUP`` + If the machine supports waking up from a suspended state and needs to reset + its devices during wake-up (from the ``MachineClass::wakeup()`` method), this + reset type should be used for such a request. Devices can utilize this reset + type to differentiate the reset requested during machine wake-up from other + reset requests. For example, RAM content must not be lost during wake-up, and + memory devices like virtio-mem that provide additional RAM must not reset + such state during wake-ups, but might do so during cold resets. However, this + reset type should not be used for wake-up detection, as not every machine + type issues a device reset request during wake-up. + ``RESET_TYPE_S390_CPU_NORMAL`` This is only used for S390 CPU objects; it clears interrupts, stops processing, and clears the TLB, but does not touch register contents. @@ -53,7 +64,6 @@ The Resettable interface handles reset types with an enum ``ResetType``: ``RESET_TYPE_S390_CPU_NORMAL`` does and also clears the PSW, prefix, FPC, timer and control registers. It does not touch gprs, fprs or acrs. - Devices which implement reset methods must treat any unknown ``ResetType`` as equivalent to ``RESET_TYPE_COLD``; this will reduce the amount of existing code we need to change if we add more types in future. diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 3d13b16768..cf0c6c580b 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -1529,12 +1529,12 @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); } -static void fby35_reset(MachineState *state, ShutdownCause reason) +static void fby35_reset(MachineState *state, ResetType type) { AspeedMachineState *bmc = ASPEED_MACHINE(state); AspeedGPIOState *gpio = &bmc->soc->gpio; - qemu_devices_reset(reason); + qemu_devices_reset(type); /* Board ID: 7 (Class-1, 4 slots) */ object_property_set_bool(OBJECT(gpio), "gpioV4", true, &error_fatal); diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index aec57c0d68..8edf57a66d 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -1254,7 +1254,7 @@ static void mps2_set_remap(Object *obj, const char *value, Error **errp) } } -static void mps2_machine_reset(MachineState *machine, ShutdownCause reason) +static void mps2_machine_reset(MachineState *machine, ResetType type) { MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine); @@ -1264,7 +1264,7 @@ static void mps2_machine_reset(MachineState *machine, ShutdownCause reason) * reset see the correct mapping. */ remap_memory(mms, mms->remap); - qemu_devices_reset(reason); + qemu_devices_reset(type); } static void mps2tz_class_init(ObjectClass *oc, void *data) diff --git a/hw/core/reset.c b/hw/core/reset.c index 58dfc8db3d..14a2639fbf 100644 --- a/hw/core/reset.c +++ b/hw/core/reset.c @@ -170,11 +170,8 @@ void qemu_unregister_resettable(Object *obj) resettable_container_remove(get_root_reset_container(), obj); } -void qemu_devices_reset(ShutdownCause reason) +void qemu_devices_reset(ResetType type) { - ResetType type = (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD) ? - RESET_TYPE_SNAPSHOT_LOAD : RESET_TYPE_COLD; - /* Reset the simulation */ resettable_reset(OBJECT(get_root_reset_container()), type); } diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 5d0a8739de..8259fe2e38 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -642,12 +642,12 @@ static void machine_HP_C3700_init(MachineState *machine) machine_HP_common_init_tail(machine, pci_bus, translate); } -static void hppa_machine_reset(MachineState *ms, ShutdownCause reason) +static void hppa_machine_reset(MachineState *ms, ResetType type) { unsigned int smp_cpus = ms->smp.cpus; int i; - qemu_devices_reset(reason); + qemu_devices_reset(type); /* Start all CPUs at the firmware entry point. * Monarch CPU will initialize firmware, secondary CPUs diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index 40edcee7af..8ae4dff7f2 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -462,7 +462,7 @@ static void microvm_machine_state_init(MachineState *machine) microvm_devices_init(mms); } -static void microvm_machine_reset(MachineState *machine, ShutdownCause reason) +static void microvm_machine_reset(MachineState *machine, ResetType type) { MicrovmMachineState *mms = MICROVM_MACHINE(machine); CPUState *cs; @@ -475,7 +475,7 @@ static void microvm_machine_reset(MachineState *machine, ShutdownCause reason) mms->kernel_cmdline_fixed = true; } - qemu_devices_reset(reason); + qemu_devices_reset(type); CPU_FOREACH(cs) { cpu = X86_CPU(cs); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 8d84c22458..80a65d965f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1712,12 +1712,12 @@ static void pc_machine_initfn(Object *obj) qemu_add_machine_init_done_notifier(&pcms->machine_done); } -static void pc_machine_reset(MachineState *machine, ShutdownCause reason) +static void pc_machine_reset(MachineState *machine, ResetType type) { CPUState *cs; X86CPU *cpu; - qemu_devices_reset(reason); + qemu_devices_reset(type); /* Reset APIC after devices have been reset to cancel * any changes that qemu_devices_reset() might have done. @@ -1732,7 +1732,7 @@ static void pc_machine_reset(MachineState *machine, ShutdownCause reason) static void pc_machine_wakeup(MachineState *machine) { cpu_synchronize_all_states(); - pc_machine_reset(machine, SHUTDOWN_CAUSE_NONE); + pc_machine_reset(machine, RESET_TYPE_WAKEUP); cpu_synchronize_all_post_reset(); } diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 9b0a6b70ab..8ff4a00c34 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -291,14 +291,14 @@ static void pegasos2_superio_write(uint8_t addr, uint8_t val) cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1); } -static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason) +static void pegasos2_machine_reset(MachineState *machine, ResetType type) { Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine); void *fdt; uint64_t d[2]; int sz; - qemu_devices_reset(reason); + qemu_devices_reset(type); if (!pm->vof) { return; /* Firmware should set up machine so nothing to do */ } diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 3526852685..988fd55d88 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -709,13 +709,13 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque) } } -static void pnv_reset(MachineState *machine, ShutdownCause reason) +static void pnv_reset(MachineState *machine, ResetType type) { PnvMachineState *pnv = PNV_MACHINE(machine); IPMIBmc *bmc; void *fdt; - qemu_devices_reset(reason); + qemu_devices_reset(type); /* * The machine should provide by default an internal BMC simulator. diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 8aa3ce7449..2c10a70a48 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1725,7 +1725,7 @@ void spapr_check_mmu_mode(bool guest_radix) } } -static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) +static void spapr_machine_reset(MachineState *machine, ResetType type) { SpaprMachineState *spapr = SPAPR_MACHINE(machine); PowerPCCPU *first_ppc_cpu; @@ -1733,7 +1733,7 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) void *fdt; int rc; - if (reason != SHUTDOWN_CAUSE_SNAPSHOT_LOAD) { + if (type != RESET_TYPE_SNAPSHOT_LOAD) { /* * Record-replay snapshot load must not consume random, this was * already replayed from initial machine reset. @@ -1762,7 +1762,7 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) spapr_setup_hpt(spapr); } - qemu_devices_reset(reason); + qemu_devices_reset(type); spapr_ovec_cleanup(spapr->ov5_cas); spapr->ov5_cas = spapr_ovec_new(); diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 18240a0fd8..5aa8d207a3 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -440,7 +440,7 @@ static void s390_pv_prepare_reset(S390CcwMachineState *ms) s390_pv_prep_reset(); } -static void s390_machine_reset(MachineState *machine, ShutdownCause reason) +static void s390_machine_reset(MachineState *machine, ResetType type) { S390CcwMachineState *ms = S390_CCW_MACHINE(machine); enum s390_reset reset_type; @@ -472,7 +472,7 @@ static void s390_machine_reset(MachineState *machine, ShutdownCause reason) * Device reset includes CPU clear resets so this has to be * done AFTER the unprotect call above. */ - qemu_devices_reset(reason); + qemu_devices_reset(type); s390_crypto_reset(); /* configure and start the ipl CPU only */ diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig index bea5be4d4a..17595ff350 100644 --- a/hw/virtio/Kconfig +++ b/hw/virtio/Kconfig @@ -16,6 +16,7 @@ config VIRTIO_PCI default y if PCI_DEVICES depends on PCI select VIRTIO + select VIRTIO_MD_SUPPORTED config VIRTIO_MMIO bool @@ -35,10 +36,17 @@ config VIRTIO_CRYPTO default y depends on VIRTIO +# not all virtio transports support memory devices; if none does, +# no need to include the code +config VIRTIO_MD_SUPPORTED + bool + config VIRTIO_MD bool + depends on VIRTIO_MD_SUPPORTED select MEM_DEVICE +# selected by the board if it has the required support code config VIRTIO_PMEM_SUPPORTED bool @@ -46,9 +54,11 @@ config VIRTIO_PMEM bool default y depends on VIRTIO + depends on VIRTIO_MD_SUPPORTED depends on VIRTIO_PMEM_SUPPORTED select VIRTIO_MD +# selected by the board if it has the required support code config VIRTIO_MEM_SUPPORTED bool @@ -57,6 +67,7 @@ config VIRTIO_MEM default y depends on VIRTIO depends on LINUX + depends on VIRTIO_MD_SUPPORTED depends on VIRTIO_MEM_SUPPORTED select VIRTIO_MD diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 4075f3d4ce..ae1e81d7ba 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -890,6 +890,9 @@ static uint64_t virtio_mem_get_features(VirtIODevice *vdev, uint64_t features, if (vmem->unplugged_inaccessible == ON_OFF_AUTO_ON) { virtio_add_feature(&features, VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE); } + if (qemu_wakeup_suspend_enabled()) { + virtio_add_feature(&features, VIRTIO_MEM_F_PERSISTENT_SUSPEND); + } return features; } @@ -902,18 +905,6 @@ static int virtio_mem_validate_features(VirtIODevice *vdev) return 0; } -static void virtio_mem_system_reset(void *opaque) -{ - VirtIOMEM *vmem = VIRTIO_MEM(opaque); - - /* - * During usual resets, we will unplug all memory and shrink the usable - * region size. This is, however, not possible in all scenarios. Then, - * the guest has to deal with this manually (VIRTIO_MEM_REQ_UNPLUG_ALL). - */ - virtio_mem_unplug_all(vmem); -} - static void virtio_mem_prepare_mr(VirtIOMEM *vmem) { const uint64_t region_size = memory_region_size(&vmem->memdev->mr); @@ -1130,7 +1121,7 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) vmstate_register_any(VMSTATE_IF(vmem), &vmstate_virtio_mem_device_early, vmem); } - qemu_register_reset(virtio_mem_system_reset, vmem); + qemu_register_resettable(OBJECT(vmem)); /* * Set ourselves as RamDiscardManager before the plug handler maps the @@ -1150,7 +1141,7 @@ static void virtio_mem_device_unrealize(DeviceState *dev) * found via an address space anymore. Unset ourselves. */ memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL); - qemu_unregister_reset(virtio_mem_system_reset, vmem); + qemu_unregister_resettable(OBJECT(vmem)); if (vmem->early_migration) { vmstate_unregister(VMSTATE_IF(vmem), &vmstate_virtio_mem_device_early, vmem); @@ -1850,12 +1841,38 @@ static void virtio_mem_unplug_request_check(VirtIOMEM *vmem, Error **errp) } } +static ResettableState *virtio_mem_get_reset_state(Object *obj) +{ + VirtIOMEM *vmem = VIRTIO_MEM(obj); + return &vmem->reset_state; +} + +static void virtio_mem_system_reset_hold(Object *obj, ResetType type) +{ + VirtIOMEM *vmem = VIRTIO_MEM(obj); + + /* + * When waking up from standby/suspend-to-ram, do not unplug any memory. + */ + if (type == RESET_TYPE_WAKEUP) { + return; + } + + /* + * During usual resets, we will unplug all memory and shrink the usable + * region size. This is, however, not possible in all scenarios. Then, + * the guest has to deal with this manually (VIRTIO_MEM_REQ_UNPLUG_ALL). + */ + virtio_mem_unplug_all(vmem); +} + static void virtio_mem_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); VirtIOMEMClass *vmc = VIRTIO_MEM_CLASS(klass); RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); device_class_set_props(dc, virtio_mem_properties); dc->vmsd = &vmstate_virtio_mem; @@ -1882,6 +1899,9 @@ static void virtio_mem_class_init(ObjectClass *klass, void *data) rdmc->replay_discarded = virtio_mem_rdm_replay_discarded; rdmc->register_listener = virtio_mem_rdm_register_listener; rdmc->unregister_listener = virtio_mem_rdm_unregister_listener; + + rc->get_state = virtio_mem_get_reset_state; + rc->phases.hold = virtio_mem_system_reset_hold; } static const TypeInfo virtio_mem_info = { diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c index 1dd96ed20f..cccc6fe761 100644 --- a/hw/virtio/virtio-qmp.c +++ b/hw/virtio/virtio-qmp.c @@ -450,6 +450,9 @@ static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = { FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \ "VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be " "accessed"), + FEATURE_ENTRY(VIRTIO_MEM_F_PERSISTENT_SUSPEND, \ + "VIRTIO_MEM_F_PERSISTENT_SUSPND: Plugged memory will remain " + "plugged when suspending+resuming"), { -1, "" } }; #endif diff --git a/include/hw/boards.h b/include/hw/boards.h index ff25c53671..5966069baa 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -10,6 +10,7 @@ #include "qemu/module.h" #include "qom/object.h" #include "hw/core/cpu.h" +#include "hw/resettable.h" #define TYPE_MACHINE_SUFFIX "-machine" @@ -257,7 +258,7 @@ struct MachineClass { const char *deprecation_reason; void (*init)(MachineState *state); - void (*reset)(MachineState *state, ShutdownCause reason); + void (*reset)(MachineState *state, ResetType type); void (*wakeup)(MachineState *state); int (*kvm_type)(MachineState *machine, const char *arg); int (*hvf_get_physical_address_range)(MachineState *machine); diff --git a/include/hw/resettable.h b/include/hw/resettable.h index 94f6f22e3c..fd862f1e9f 100644 --- a/include/hw/resettable.h +++ b/include/hw/resettable.h @@ -29,6 +29,7 @@ typedef struct ResettableState ResettableState; * Types of reset. * * + Cold: reset resulting from a power cycle of the object. + * + Wakeup: reset resulting from a wake-up from a suspended state. * * TODO: Support has to be added to handle more types. In particular, * ResettableState structure needs to be expanded. @@ -36,6 +37,7 @@ typedef struct ResettableState ResettableState; typedef enum ResetType { RESET_TYPE_COLD, RESET_TYPE_SNAPSHOT_LOAD, + RESET_TYPE_WAKEUP, RESET_TYPE_S390_CPU_INITIAL, RESET_TYPE_S390_CPU_NORMAL, } ResetType; diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h index 5f5b02b8f9..a1af144c28 100644 --- a/include/hw/virtio/virtio-mem.h +++ b/include/hw/virtio/virtio-mem.h @@ -14,6 +14,7 @@ #define HW_VIRTIO_MEM_H #include "standard-headers/linux/virtio_mem.h" +#include "hw/resettable.h" #include "hw/virtio/virtio.h" #include "qapi/qapi-types-misc.h" #include "sysemu/hostmem.h" @@ -115,6 +116,9 @@ struct VirtIOMEM { /* listeners to notify on plug/unplug activity. */ QLIST_HEAD(, RamDiscardListener) rdl_list; + + /* State of the resettable container */ + ResettableState reset_state; }; struct VirtIOMEMClass { diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h index ae436044a9..0e297c0e02 100644 --- a/include/sysemu/reset.h +++ b/include/sysemu/reset.h @@ -27,6 +27,7 @@ #ifndef QEMU_SYSEMU_RESET_H #define QEMU_SYSEMU_RESET_H +#include "hw/resettable.h" #include "qapi/qapi-events-run-state.h" typedef void QEMUResetHandler(void *opaque); @@ -110,7 +111,7 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); /** * qemu_devices_reset: Perform a complete system reset - * @reason: reason for the reset + * @reason: type of the reset * * This function performs the low-level work needed to do a complete reset * of the system (calling all the callbacks registered with @@ -121,6 +122,6 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); * If you want to trigger a system reset from, for instance, a device * model, don't use this function. Use qemu_system_reset_request(). */ -void qemu_devices_reset(ShutdownCause reason); +void qemu_devices_reset(ResetType type); #endif diff --git a/system/runstate.c b/system/runstate.c index a0e2a5fd22..c2c9afa905 100644 --- a/system/runstate.c +++ b/system/runstate.c @@ -32,6 +32,7 @@ #include "exec/cpu-common.h" #include "gdbstub/syscalls.h" #include "hw/boards.h" +#include "hw/resettable.h" #include "migration/misc.h" #include "migration/postcopy-ram.h" #include "monitor/monitor.h" @@ -507,15 +508,23 @@ static int qemu_debug_requested(void) void qemu_system_reset(ShutdownCause reason) { MachineClass *mc; + ResetType type; mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; cpu_synchronize_all_states(); + switch (reason) { + case SHUTDOWN_CAUSE_SNAPSHOT_LOAD: + type = RESET_TYPE_SNAPSHOT_LOAD; + break; + default: + type = RESET_TYPE_COLD; + } if (mc && mc->reset) { - mc->reset(current_machine, reason); + mc->reset(current_machine, type); } else { - qemu_devices_reset(reason); + qemu_devices_reset(type); } switch (reason) { case SHUTDOWN_CAUSE_NONE: |