When a guests reboots with diagnose 308 subcode 3 it requests the memory to be cleared. We did not do it so far. This does not only violate the architecture, it also misses the chance to free up that memory on reboot, which would help on host memory over commitment. By using ram_block_discard_range we can cover both cases.
Signed-off-by: Christian Borntraeger <borntrae...@de.ibm.com> --- target/s390x/kvm.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index 8f3a422288..2e145ad5c3 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -34,6 +34,8 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/timer.h" +#include "qemu/rcu_queue.h" +#include "sysemu/cpus.h" #include "sysemu/sysemu.h" #include "sysemu/hw_accel.h" #include "hw/boards.h" @@ -41,6 +43,7 @@ #include "sysemu/device_tree.h" #include "exec/gdbstub.h" #include "exec/address-spaces.h" +#include "exec/ram_addr.h" #include "trace.h" #include "qapi-event.h" #include "hw/s390x/s390-pci-inst.h" @@ -1841,6 +1844,14 @@ static int kvm_arch_handle_debug_exit(S390CPU *cpu) return ret; } +static void release_all_rams(void) +{ + struct RAMBlock *rb; + + QLIST_FOREACH_RCU(rb, &ram_list.blocks, next) + ram_block_discard_range(rb, 0, rb->used_length); +} + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { S390CPU *cpu = S390_CPU(cs); @@ -1853,6 +1864,14 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) ret = handle_intercept(cpu); break; case KVM_EXIT_S390_RESET: + if (run->s390_reset_flags & KVM_S390_RESET_CLEAR) { + /* + * We will stop other CPUs anyway, avoid spurious crashes and + * get all CPUs out. The reset will take care of the resume. + */ + pause_all_vcpus(); + release_all_rams(); + } s390_reipl_request(); break; case KVM_EXIT_S390_TSCH: -- 2.14.3