Pablo Greco e6a3ae
From 4949ead0219a44a8419ac6726f219aafd0f91137 Mon Sep 17 00:00:00 2001
Pablo Greco e6a3ae
From: Cornelia Huck <cohuck@redhat.com>
Pablo Greco e6a3ae
Date: Wed, 17 Apr 2019 13:57:40 +0100
Pablo Greco e6a3ae
Subject: [PATCH 23/24] s390x: refactor reset/reipl handling
Pablo Greco e6a3ae
Pablo Greco e6a3ae
RH-Author: Cornelia Huck <cohuck@redhat.com>
Pablo Greco e6a3ae
Message-id: <20190417135741.25297-24-cohuck@redhat.com>
Pablo Greco e6a3ae
Patchwork-id: 85802
Pablo Greco e6a3ae
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH v2 23/24] s390x: refactor reset/reipl handling
Pablo Greco e6a3ae
Bugzilla: 1699070
Pablo Greco e6a3ae
RH-Acked-by: David Hildenbrand <david@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Thomas Huth <thuth@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
From: David Hildenbrand <david@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Calling pause_all_vcpus()/resume_all_vcpus() from a VCPU thread might
Pablo Greco e6a3ae
not be the best idea. As pause_all_vcpus() temporarily drops the qemu
Pablo Greco e6a3ae
mutex, two parallel calls to pause_all_vcpus() can be active at a time,
Pablo Greco e6a3ae
resulting in a deadlock. (either by two VCPUs or by the main thread and a
Pablo Greco e6a3ae
VCPU)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Let's handle it via the main loop instead, as suggested by Paolo. If we
Pablo Greco e6a3ae
would have two parallel reset requests by two different VCPUs at the
Pablo Greco e6a3ae
same time, the last one would win.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
We use the existing ipl device to handle it. The nice side effect is
Pablo Greco e6a3ae
that we can get rid of reipl_requested.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
This change implies that all reset handling now goes via the common
Pablo Greco e6a3ae
path, so "no-reboot" handling is now active for all kinds of reboots.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Let's execute any CPU initialization code on the target CPU using
Pablo Greco e6a3ae
run_on_cpu.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Signed-off-by: David Hildenbrand <david@redhat.com>
Pablo Greco e6a3ae
Message-Id: <20180424101859.10239-1-david@redhat.com>
Pablo Greco e6a3ae
Acked-by: Thomas Huth <thuth@redhat.com>
Pablo Greco e6a3ae
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Pablo Greco e6a3ae
(cherry picked from commit a30fb811cbe940020a498d2cdac9326cac38b4d9)
Pablo Greco e6a3ae
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Pablo Greco e6a3ae
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Pablo Greco e6a3ae
---
Pablo Greco e6a3ae
 hw/s390x/ipl.c                     | 43 +++++++++++++++++++++++----
Pablo Greco e6a3ae
 hw/s390x/ipl.h                     | 16 ++++++++--
Pablo Greco e6a3ae
 hw/s390x/s390-virtio-ccw.c         | 51 ++++++++++++++++++++++++++-----
Pablo Greco e6a3ae
 include/hw/s390x/s390-virtio-ccw.h |  2 --
Pablo Greco e6a3ae
 target/s390x/cpu.h                 | 26 ++++++++++++++++
Pablo Greco e6a3ae
 target/s390x/diag.c                | 61 +++-----------------------------------
Pablo Greco e6a3ae
 target/s390x/internal.h            |  6 ----
Pablo Greco e6a3ae
 target/s390x/kvm.c                 |  2 +-
Pablo Greco e6a3ae
 8 files changed, 127 insertions(+), 80 deletions(-)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
Pablo Greco e6a3ae
index 10038ec..ee6701e 100644
Pablo Greco e6a3ae
--- a/hw/s390x/ipl.c
Pablo Greco e6a3ae
+++ b/hw/s390x/ipl.c
Pablo Greco e6a3ae
@@ -26,6 +26,7 @@
Pablo Greco e6a3ae
 #include "qemu/config-file.h"
Pablo Greco e6a3ae
 #include "qemu/cutils.h"
Pablo Greco e6a3ae
 #include "qemu/option.h"
Pablo Greco e6a3ae
+#include "exec/exec-all.h"
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 #define KERN_IMAGE_START                0x010000UL
Pablo Greco e6a3ae
 #define LINUX_MAGIC_ADDR                0x010008UL
Pablo Greco e6a3ae
@@ -511,12 +512,20 @@ IplParameterBlock *s390_ipl_get_iplb(void)
Pablo Greco e6a3ae
     return &ipl->iplb;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-void s390_reipl_request(void)
Pablo Greco e6a3ae
+void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     S390IPLState *ipl = get_ipl_device();
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-    ipl->reipl_requested = true;
Pablo Greco e6a3ae
-    if (ipl->iplb_valid &&
Pablo Greco e6a3ae
+    if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) {
Pablo Greco e6a3ae
+        /* use CPU 0 for full resets */
Pablo Greco e6a3ae
+        ipl->reset_cpu_index = 0;
Pablo Greco e6a3ae
+    } else {
Pablo Greco e6a3ae
+        ipl->reset_cpu_index = cs->cpu_index;
Pablo Greco e6a3ae
+    }
Pablo Greco e6a3ae
+    ipl->reset_type = reset_type;
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+    if (reset_type == S390_RESET_REIPL &&
Pablo Greco e6a3ae
+        ipl->iplb_valid &&
Pablo Greco e6a3ae
         !ipl->netboot &&
Pablo Greco e6a3ae
         ipl->iplb.pbt == S390_IPL_TYPE_CCW &&
Pablo Greco e6a3ae
         is_virtio_scsi_device(&ipl->iplb)) {
Pablo Greco e6a3ae
@@ -533,6 +542,31 @@ void s390_reipl_request(void)
Pablo Greco e6a3ae
         }
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
     qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
Pablo Greco e6a3ae
+    /* as this is triggered by a CPU, make sure to exit the loop */
Pablo Greco e6a3ae
+    if (tcg_enabled()) {
Pablo Greco e6a3ae
+        cpu_loop_exit(cs);
Pablo Greco e6a3ae
+    }
Pablo Greco e6a3ae
+}
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type)
Pablo Greco e6a3ae
+{
Pablo Greco e6a3ae
+    S390IPLState *ipl = get_ipl_device();
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+    *cs = qemu_get_cpu(ipl->reset_cpu_index);
Pablo Greco e6a3ae
+    if (!*cs) {
Pablo Greco e6a3ae
+        /* use any CPU */
Pablo Greco e6a3ae
+        *cs = first_cpu;
Pablo Greco e6a3ae
+    }
Pablo Greco e6a3ae
+    *reset_type = ipl->reset_type;
Pablo Greco e6a3ae
+}
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+void s390_ipl_clear_reset_request(void)
Pablo Greco e6a3ae
+{
Pablo Greco e6a3ae
+    S390IPLState *ipl = get_ipl_device();
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+    ipl->reset_type = S390_RESET_EXTERNAL;
Pablo Greco e6a3ae
+    /* use CPU 0 for full resets */
Pablo Greco e6a3ae
+    ipl->reset_cpu_index = 0;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 static void s390_ipl_prepare_qipl(S390CPU *cpu)
Pablo Greco e6a3ae
@@ -579,11 +613,10 @@ static void s390_ipl_reset(DeviceState *dev)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     S390IPLState *ipl = S390_IPL(dev);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-    if (!ipl->reipl_requested) {
Pablo Greco e6a3ae
+    if (ipl->reset_type != S390_RESET_REIPL) {
Pablo Greco e6a3ae
         ipl->iplb_valid = false;
Pablo Greco e6a3ae
         memset(&ipl->iplb, 0, sizeof(IplParameterBlock));
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
-    ipl->reipl_requested = false;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 static void s390_ipl_class_init(ObjectClass *klass, void *data)
Pablo Greco e6a3ae
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
Pablo Greco e6a3ae
index 0570d0a..4e87b89 100644
Pablo Greco e6a3ae
--- a/hw/s390x/ipl.h
Pablo Greco e6a3ae
+++ b/hw/s390x/ipl.h
Pablo Greco e6a3ae
@@ -87,7 +87,17 @@ int s390_ipl_set_loadparm(uint8_t *loadparm);
Pablo Greco e6a3ae
 void s390_ipl_update_diag308(IplParameterBlock *iplb);
Pablo Greco e6a3ae
 void s390_ipl_prepare_cpu(S390CPU *cpu);
Pablo Greco e6a3ae
 IplParameterBlock *s390_ipl_get_iplb(void);
Pablo Greco e6a3ae
-void s390_reipl_request(void);
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+enum s390_reset {
Pablo Greco e6a3ae
+    /* default is a reset not triggered by a CPU e.g. issued by QMP */
Pablo Greco e6a3ae
+    S390_RESET_EXTERNAL = 0,
Pablo Greco e6a3ae
+    S390_RESET_REIPL,
Pablo Greco e6a3ae
+    S390_RESET_MODIFIED_CLEAR,
Pablo Greco e6a3ae
+    S390_RESET_LOAD_NORMAL,
Pablo Greco e6a3ae
+};
Pablo Greco e6a3ae
+void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type);
Pablo Greco e6a3ae
+void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type);
Pablo Greco e6a3ae
+void s390_ipl_clear_reset_request(void);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 #define QIPL_ADDRESS  0xcc
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
@@ -129,9 +139,11 @@ struct S390IPLState {
Pablo Greco e6a3ae
     bool enforce_bios;
Pablo Greco e6a3ae
     IplParameterBlock iplb;
Pablo Greco e6a3ae
     bool iplb_valid;
Pablo Greco e6a3ae
-    bool reipl_requested;
Pablo Greco e6a3ae
     bool netboot;
Pablo Greco e6a3ae
     QemuIplParameters qipl;
Pablo Greco e6a3ae
+    /* reset related properties don't have to be migrated or reset */
Pablo Greco e6a3ae
+    enum s390_reset reset_type;
Pablo Greco e6a3ae
+    int reset_cpu_index;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     /*< public >*/
Pablo Greco e6a3ae
     char *kernel;
Pablo Greco e6a3ae
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
Pablo Greco e6a3ae
index 8f93edc..ba90e4f 100644
Pablo Greco e6a3ae
--- a/hw/s390x/s390-virtio-ccw.c
Pablo Greco e6a3ae
+++ b/hw/s390x/s390-virtio-ccw.c
Pablo Greco e6a3ae
@@ -95,7 +95,7 @@ static const char *const reset_dev_types[] = {
Pablo Greco e6a3ae
     "diag288",
Pablo Greco e6a3ae
 };
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-void subsystem_reset(void)
Pablo Greco e6a3ae
+static void subsystem_reset(void)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     DeviceState *dev;
Pablo Greco e6a3ae
     int i;
Pablo Greco e6a3ae
@@ -317,17 +317,54 @@ static void s390_cpu_plug(HotplugHandler *hotplug_dev,
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
+static inline void s390_do_cpu_ipl(CPUState *cs, run_on_cpu_data arg)
Pablo Greco e6a3ae
+{
Pablo Greco e6a3ae
+    S390CPU *cpu = S390_CPU(cs);
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+    s390_ipl_prepare_cpu(cpu);
Pablo Greco e6a3ae
+    s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
Pablo Greco e6a3ae
+}
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
 static void s390_machine_reset(void)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
-    S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0));
Pablo Greco e6a3ae
+    enum s390_reset reset_type;
Pablo Greco e6a3ae
+    CPUState *cs, *t;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
+    /* get the reset parameters, reset them once done */
Pablo Greco e6a3ae
+    s390_ipl_get_reset_request(&cs, &reset_type);
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+    /* all CPUs are paused and synchronized at this point */
Pablo Greco e6a3ae
     s390_cmma_reset();
Pablo Greco e6a3ae
-    qemu_devices_reset();
Pablo Greco e6a3ae
-    s390_crypto_reset();
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-    /* all cpus are stopped - configure and start the ipl cpu only */
Pablo Greco e6a3ae
-    s390_ipl_prepare_cpu(ipl_cpu);
Pablo Greco e6a3ae
-    s390_cpu_set_state(S390_CPU_STATE_OPERATING, ipl_cpu);
Pablo Greco e6a3ae
+    switch (reset_type) {
Pablo Greco e6a3ae
+    case S390_RESET_EXTERNAL:
Pablo Greco e6a3ae
+    case S390_RESET_REIPL:
Pablo Greco e6a3ae
+        qemu_devices_reset();
Pablo Greco e6a3ae
+        s390_crypto_reset();
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+        /* configure and start the ipl CPU only */
Pablo Greco e6a3ae
+        run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL);
Pablo Greco e6a3ae
+        break;
Pablo Greco e6a3ae
+    case S390_RESET_MODIFIED_CLEAR:
Pablo Greco e6a3ae
+        CPU_FOREACH(t) {
Pablo Greco e6a3ae
+            run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
Pablo Greco e6a3ae
+        }
Pablo Greco e6a3ae
+        subsystem_reset();
Pablo Greco e6a3ae
+        s390_crypto_reset();
Pablo Greco e6a3ae
+        run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
Pablo Greco e6a3ae
+        break;
Pablo Greco e6a3ae
+    case S390_RESET_LOAD_NORMAL:
Pablo Greco e6a3ae
+        CPU_FOREACH(t) {
Pablo Greco e6a3ae
+            run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
Pablo Greco e6a3ae
+        }
Pablo Greco e6a3ae
+        subsystem_reset();
Pablo Greco e6a3ae
+        run_on_cpu(cs, s390_do_cpu_initial_reset, RUN_ON_CPU_NULL);
Pablo Greco e6a3ae
+        run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
Pablo Greco e6a3ae
+        break;
Pablo Greco e6a3ae
+    default:
Pablo Greco e6a3ae
+        g_assert_not_reached();
Pablo Greco e6a3ae
+    }
Pablo Greco e6a3ae
+    s390_ipl_clear_reset_request();
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
Pablo Greco e6a3ae
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
Pablo Greco e6a3ae
index ac896e3..ab88d49 100644
Pablo Greco e6a3ae
--- a/include/hw/s390x/s390-virtio-ccw.h
Pablo Greco e6a3ae
+++ b/include/hw/s390x/s390-virtio-ccw.h
Pablo Greco e6a3ae
@@ -53,6 +53,4 @@ bool cpu_model_allowed(void);
Pablo Greco e6a3ae
  */
Pablo Greco e6a3ae
 bool css_migration_enabled(void);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-void subsystem_reset(void);
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
 #endif
Pablo Greco e6a3ae
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
Pablo Greco e6a3ae
index 6500f42..21b2f21 100644
Pablo Greco e6a3ae
--- a/target/s390x/cpu.h
Pablo Greco e6a3ae
+++ b/target/s390x/cpu.h
Pablo Greco e6a3ae
@@ -687,6 +687,32 @@ static inline uint64_t s390_build_validity_mcic(void)
Pablo Greco e6a3ae
     return mcic;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
+static inline void s390_do_cpu_full_reset(CPUState *cs, run_on_cpu_data arg)
Pablo Greco e6a3ae
+{
Pablo Greco e6a3ae
+    cpu_reset(cs);
Pablo Greco e6a3ae
+}
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+static inline void s390_do_cpu_reset(CPUState *cs, run_on_cpu_data arg)
Pablo Greco e6a3ae
+{
Pablo Greco e6a3ae
+    S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+    scc->cpu_reset(cs);
Pablo Greco e6a3ae
+}
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+static inline void s390_do_cpu_initial_reset(CPUState *cs, run_on_cpu_data arg)
Pablo Greco e6a3ae
+{
Pablo Greco e6a3ae
+    S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+    scc->initial_cpu_reset(cs);
Pablo Greco e6a3ae
+}
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+static inline void s390_do_cpu_load_normal(CPUState *cs, run_on_cpu_data arg)
Pablo Greco e6a3ae
+{
Pablo Greco e6a3ae
+    S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
+    scc->load_normal(cs);
Pablo Greco e6a3ae
+}
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 /* cpu.c */
Pablo Greco e6a3ae
 void s390_crypto_reset(void);
Pablo Greco e6a3ae
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
Pablo Greco e6a3ae
index 50b58df..b5d5f8e 100644
Pablo Greco e6a3ae
--- a/target/s390x/diag.c
Pablo Greco e6a3ae
+++ b/target/s390x/diag.c
Pablo Greco e6a3ae
@@ -22,51 +22,6 @@
Pablo Greco e6a3ae
 #include "hw/s390x/ipl.h"
Pablo Greco e6a3ae
 #include "hw/s390x/s390-virtio-ccw.h"
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-static int modified_clear_reset(S390CPU *cpu)
Pablo Greco e6a3ae
-{
Pablo Greco e6a3ae
-    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
Pablo Greco e6a3ae
-    CPUState *t;
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
-    pause_all_vcpus();
Pablo Greco e6a3ae
-    cpu_synchronize_all_states();
Pablo Greco e6a3ae
-    CPU_FOREACH(t) {
Pablo Greco e6a3ae
-        run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
Pablo Greco e6a3ae
-    }
Pablo Greco e6a3ae
-    s390_cmma_reset();
Pablo Greco e6a3ae
-    subsystem_reset();
Pablo Greco e6a3ae
-    s390_crypto_reset();
Pablo Greco e6a3ae
-    scc->load_normal(CPU(cpu));
Pablo Greco e6a3ae
-    cpu_synchronize_all_post_reset();
Pablo Greco e6a3ae
-    resume_all_vcpus();
Pablo Greco e6a3ae
-    return 0;
Pablo Greco e6a3ae
-}
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
-static inline void s390_do_cpu_reset(CPUState *cs, run_on_cpu_data arg)
Pablo Greco e6a3ae
-{
Pablo Greco e6a3ae
-    S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
-    scc->cpu_reset(cs);
Pablo Greco e6a3ae
-}
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
-static int load_normal_reset(S390CPU *cpu)
Pablo Greco e6a3ae
-{
Pablo Greco e6a3ae
-    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
Pablo Greco e6a3ae
-    CPUState *t;
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
-    pause_all_vcpus();
Pablo Greco e6a3ae
-    cpu_synchronize_all_states();
Pablo Greco e6a3ae
-    CPU_FOREACH(t) {
Pablo Greco e6a3ae
-        run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
Pablo Greco e6a3ae
-    }
Pablo Greco e6a3ae
-    s390_cmma_reset();
Pablo Greco e6a3ae
-    subsystem_reset();
Pablo Greco e6a3ae
-    scc->initial_cpu_reset(CPU(cpu));
Pablo Greco e6a3ae
-    scc->load_normal(CPU(cpu));
Pablo Greco e6a3ae
-    cpu_synchronize_all_post_reset();
Pablo Greco e6a3ae
-    resume_all_vcpus();
Pablo Greco e6a3ae
-    return 0;
Pablo Greco e6a3ae
-}
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
 int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
     uint64_t func = env->regs[r1];
Pablo Greco e6a3ae
@@ -101,6 +56,7 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
+    CPUState *cs = CPU(s390_env_get_cpu(env));
Pablo Greco e6a3ae
     uint64_t addr =  env->regs[r1];
Pablo Greco e6a3ae
     uint64_t subcode = env->regs[r3];
Pablo Greco e6a3ae
     IplParameterBlock *iplb;
Pablo Greco e6a3ae
@@ -117,22 +73,13 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     switch (subcode) {
Pablo Greco e6a3ae
     case 0:
Pablo Greco e6a3ae
-        modified_clear_reset(s390_env_get_cpu(env));
Pablo Greco e6a3ae
-        if (tcg_enabled()) {
Pablo Greco e6a3ae
-            cpu_loop_exit(CPU(s390_env_get_cpu(env)));
Pablo Greco e6a3ae
-        }
Pablo Greco e6a3ae
+        s390_ipl_reset_request(cs, S390_RESET_MODIFIED_CLEAR);
Pablo Greco e6a3ae
         break;
Pablo Greco e6a3ae
     case 1:
Pablo Greco e6a3ae
-        load_normal_reset(s390_env_get_cpu(env));
Pablo Greco e6a3ae
-        if (tcg_enabled()) {
Pablo Greco e6a3ae
-            cpu_loop_exit(CPU(s390_env_get_cpu(env)));
Pablo Greco e6a3ae
-        }
Pablo Greco e6a3ae
+        s390_ipl_reset_request(cs, S390_RESET_LOAD_NORMAL);
Pablo Greco e6a3ae
         break;
Pablo Greco e6a3ae
     case 3:
Pablo Greco e6a3ae
-        s390_reipl_request();
Pablo Greco e6a3ae
-        if (tcg_enabled()) {
Pablo Greco e6a3ae
-            cpu_loop_exit(CPU(s390_env_get_cpu(env)));
Pablo Greco e6a3ae
-        }
Pablo Greco e6a3ae
+        s390_ipl_reset_request(cs, S390_RESET_REIPL);
Pablo Greco e6a3ae
         break;
Pablo Greco e6a3ae
     case 5:
Pablo Greco e6a3ae
         if ((r1 & 1) || (addr & 0x0fffULL)) {
Pablo Greco e6a3ae
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
Pablo Greco e6a3ae
index 61a509d..f2a771e 100644
Pablo Greco e6a3ae
--- a/target/s390x/internal.h
Pablo Greco e6a3ae
+++ b/target/s390x/internal.h
Pablo Greco e6a3ae
@@ -258,12 +258,6 @@ static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb,
Pablo Greco e6a3ae
 /* Base/displacement are at the same locations. */
Pablo Greco e6a3ae
 #define decode_basedisp_rs decode_basedisp_s
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-static inline void s390_do_cpu_full_reset(CPUState *cs, run_on_cpu_data arg)
Pablo Greco e6a3ae
-{
Pablo Greco e6a3ae
-    cpu_reset(cs);
Pablo Greco e6a3ae
-}
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
 /* arch_dump.c */
Pablo Greco e6a3ae
 int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
Pablo Greco e6a3ae
                               int cpuid, void *opaque);
Pablo Greco e6a3ae
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
Pablo Greco e6a3ae
index 1cf117b..114502d 100644
Pablo Greco e6a3ae
--- a/target/s390x/kvm.c
Pablo Greco e6a3ae
+++ b/target/s390x/kvm.c
Pablo Greco e6a3ae
@@ -1826,7 +1826,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
Pablo Greco e6a3ae
             ret = handle_intercept(cpu);
Pablo Greco e6a3ae
             break;
Pablo Greco e6a3ae
         case KVM_EXIT_S390_RESET:
Pablo Greco e6a3ae
-            s390_reipl_request();
Pablo Greco e6a3ae
+            s390_ipl_reset_request(cs, S390_RESET_REIPL);
Pablo Greco e6a3ae
             break;
Pablo Greco e6a3ae
         case KVM_EXIT_S390_TSCH:
Pablo Greco e6a3ae
             ret = handle_tsch(cpu);
Pablo Greco e6a3ae
-- 
Pablo Greco e6a3ae
1.8.3.1
Pablo Greco e6a3ae