summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--cpus.c14
-rw-r--r--hmp-commands.hx4
-rw-r--r--qmp-commands.hx2
-rw-r--r--target-s390x/cpu.h13
-rw-r--r--target-s390x/kvm.c6
5 files changed, 33 insertions, 6 deletions
diff --git a/cpus.c b/cpus.c
index b9e5685e16..d74cc117b3 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1401,6 +1401,20 @@ void qmp_inject_nmi(Error **errp)
             apic_deliver_nmi(env->apic_state);
         }
     }
+#elif defined(TARGET_S390X)
+    CPUState *cs;
+    S390CPU *cpu;
+
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        cpu = S390_CPU(cs);
+        if (cpu->env.cpu_num == monitor_get_cpu_index()) {
+            if (s390_cpu_restart(S390_CPU(cs)) == -1) {
+                error_set(errp, QERR_UNSUPPORTED);
+                return;
+            }
+            break;
+        }
+    }
 #else
     error_set(errp, QERR_UNSUPPORTED);
 #endif
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8c6b91a9c7..628807f684 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -822,7 +822,7 @@ The values that can be specified here depend on the machine type, but are
 the same that can be specified in the @code{-boot} command line option.
 ETEXI
 
-#if defined(TARGET_I386)
+#if defined(TARGET_I386) || defined(TARGET_S390X)
     {
         .name       = "nmi",
         .args_type  = "",
@@ -834,7 +834,7 @@ ETEXI
 STEXI
 @item nmi @var{cpu}
 @findex nmi
-Inject an NMI on the given CPU (x86 only).
+Inject an NMI (x86) or RESTART (s390x) on the given CPU.
 
 ETEXI
 
diff --git a/qmp-commands.hx b/qmp-commands.hx
index cf47e3fe72..bb09e72712 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -487,7 +487,7 @@ Example:
 <- { "return": {} }
 
 Note: inject-nmi fails when the guest doesn't support injecting.
-      Currently, only x86 guests do.
+      Currently, only x86 (NMI) and s390x (RESTART) guests do.
 
 EQMP
 
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index b866ea189d..8be5648806 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1069,6 +1069,7 @@ void kvm_s390_enable_css_support(S390CPU *cpu);
 int kvm_s390_get_registers_partial(CPUState *cpu);
 int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
                                     int vq, bool assign);
+int kvm_s390_cpu_restart(S390CPU *cpu);
 #else
 static inline void kvm_s390_io_interrupt(S390CPU *cpu,
                                         uint16_t subchannel_id,
@@ -1093,8 +1094,20 @@ static inline int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier,
 {
     return -ENOSYS;
 }
+static inline int kvm_s390_cpu_restart(S390CPU *cpu)
+{
+    return -ENOSYS;
+}
 #endif
 
+static inline int s390_cpu_restart(S390CPU *cpu)
+{
+    if (kvm_enabled()) {
+        return kvm_s390_cpu_restart(cpu);
+    }
+    return -ENOSYS;
+}
+
 static inline void s390_io_interrupt(S390CPU *cpu,
                                      uint16_t subchannel_id,
                                      uint16_t subchannel_nr,
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index c7fcdfa882..185c8f5a45 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -612,12 +612,12 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code)
     return r;
 }
 
-static int s390_cpu_restart(S390CPU *cpu)
+int kvm_s390_cpu_restart(S390CPU *cpu)
 {
     kvm_s390_interrupt(cpu, KVM_S390_RESTART, 0);
     s390_add_running_cpu(cpu);
     qemu_cpu_kick(CPU(cpu));
-    DPRINTF("DONE: SIGP cpu restart: %p\n", &cpu->env);
+    DPRINTF("DONE: KVM cpu restart: %p\n", &cpu->env);
     return 0;
 }
 
@@ -686,7 +686,7 @@ static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
 
     switch (order_code) {
         case SIGP_RESTART:
-            r = s390_cpu_restart(target_cpu);
+            r = kvm_s390_cpu_restart(target_cpu);
             break;
         case SIGP_STORE_STATUS_ADDR:
             r = s390_store_status(target_env, parameter);