s390x/ipl: drop reipl parameters on resets
authorFan Zhang <zhangfan@linux.vnet.ibm.com>
Thu, 12 Feb 2015 17:02:15 +0000 (18:02 +0100)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Fri, 13 Feb 2015 15:14:09 +0000 (16:14 +0100)
Whenever a reboot initiated by the guest is done, the reipl parameters should
remain valid. The disk configured by the guest is to be used for
ipl'ing. External reboot/reset request (e.g. via virsh reset guest) should
completely reset the guest to the initial state, and therefore also reset the
reipl parameters, resulting in an ipl behaviour of the initially configured
guest. This could be an external kernel or a disk.

Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Fan Zhang <zhangfan@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
hw/s390x/ipl.c
hw/s390x/ipl.h
target-s390x/kvm.c

index 231713dbc36590e5a2b33d28d1a7eaaa34f8322e..a1aa051eff9722e918f6185788f7385546235b46 100644 (file)
@@ -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);
index f1d082ff45e60488f6ef2931f84a2ab55b7d153a..70497bc65f46de6e74d75f0588cb31bdf5dc6ff2 100644 (file)
@@ -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
index 6f2d5b492412768c7f7e48335476b6c2bce73826..8c2f228fa60d1545e362d55d3094c9a9c1537a48 100644 (file)
@@ -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);