aboutsummaryrefslogtreecommitdiff
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);