diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 231713dbc3..a1aa051eff 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -55,6 +55,7 @@ typedef struct S390IPLState { bool enforce_bios; IplParameterBlock iplb; bool iplb_valid; + bool reipl_requested; /*< public >*/ char *kernel; @@ -233,6 +234,15 @@ IplParameterBlock *s390_ipl_get_iplb(void) return &ipl->iplb; } +void s390_reipl_request(void) +{ + S390IPLState *ipl; + + ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL)); + ipl->reipl_requested = true; + qemu_system_reset_request(); +} + static void s390_ipl_reset(DeviceState *dev) { S390IPLState *ipl = S390_IPL(dev); @@ -242,6 +252,11 @@ static void s390_ipl_reset(DeviceState *dev) env->psw.addr = ipl->start_addr; env->psw.mask = IPL_PSW_MASK; + if (!ipl->reipl_requested) { + ipl->iplb_valid = false; + } + ipl->reipl_requested = false; + if (!ipl->kernel || ipl->iplb_valid) { env->psw.addr = ipl->bios_start_addr; env->regs[7] = s390_update_iplstate(env, ipl); diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index f1d082ff45..70497bc65f 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -20,5 +20,6 @@ typedef struct IplParameterBlock { int s390_ipl_update_diag308(IplParameterBlock *iplb); IplParameterBlock *s390_ipl_get_iplb(void); +void s390_reipl_request(void); #endif diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 6f2d5b4924..8c2f228fa6 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -42,6 +42,7 @@ #include "qapi-event.h" #include "hw/s390x/s390-pci-inst.h" #include "hw/s390x/s390-pci-bus.h" +#include "hw/s390x/ipl.h" /* #define DEBUG_KVM */ @@ -1397,7 +1398,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) ret = handle_intercept(cpu); break; case KVM_EXIT_S390_RESET: - qemu_system_reset_request(); + s390_reipl_request(); break; case KVM_EXIT_S390_TSCH: ret = handle_tsch(cpu);