Presently s390x is the only architecture not exposing specific
CPU information via QMP query-cpus. Upstream discussion has shown
that it could make sense to report the architecture specific CPU
state, e.g. to detect that a CPU has been stopped.
With this change the output of query-cpus will look like this on
s390:
[
{"arch": "s390", "current": true,
"props": {"core-id": 0}, "cpu-state": "operating", "CPU": 0,
"qom_path": "/machine/unattached/device[0]",
"halted": false, "thread_id": 63115},
{"arch": "s390", "current": false,
"props": {"core-id": 1}, "cpu-state": "stopped", "CPU": 1,
"qom_path": "/machine/unattached/device[1]",
"halted": true, "thread_id": 63116}
]
Signed-off-by: Viktor Mihajlovski
---
v1 -> v2:
- qapi-schema.json: fixed style issues, typos, improved enum naming
- hmp.c: added missing newline (printing cpu state)
cpus.c | 6 ++
hmp.c | 4
hw/s390x/s390-virtio-ccw.c | 2 +-
qapi-schema.json | 28 +++-
target/s390x/cpu.c | 24
target/s390x/cpu.h | 7 ++-
target/s390x/kvm.c | 8
target/s390x/sigp.c| 38 +++---
8 files changed, 75 insertions(+), 42 deletions(-)
diff --git a/cpus.c b/cpus.c
index 2cb0af9..39e46dd 100644
--- a/cpus.c
+++ b/cpus.c
@@ -2033,6 +2033,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
#elif defined(TARGET_TRICORE)
TriCoreCPU *tricore_cpu = TRICORE_CPU(cpu);
CPUTriCoreState *env = &tricore_cpu->env;
+#elif defined(TARGET_S390X)
+S390CPU *s390_cpu = S390_CPU(cpu);
+CPUS390XState *env = &s390_cpu->env;
#endif
cpu_synchronize_state(cpu);
@@ -2060,6 +2063,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
#elif defined(TARGET_TRICORE)
info->value->arch = CPU_INFO_ARCH_TRICORE;
info->value->u.tricore.PC = env->PC;
+#elif defined(TARGET_S390X)
+info->value->arch = CPU_INFO_ARCH_S390;
+info->value->u.s390.cpu_state = env->cpu_state;
#else
info->value->arch = CPU_INFO_ARCH_OTHER;
#endif
diff --git a/hmp.c b/hmp.c
index b3de32d..219f769 100644
--- a/hmp.c
+++ b/hmp.c
@@ -390,6 +390,10 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
case CPU_INFO_ARCH_TRICORE:
monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.tricore.PC);
break;
+case CPU_INFO_ARCH_S390:
+monitor_printf(mon, " state=%s\n",
+ CpuS390State_str(cpu->value->u.s390.cpu_state));
+break;
default:
break;
}
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 3807dcb..a7ad7e7 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -373,7 +373,7 @@ static void s390_machine_reset(void)
/* all cpus are stopped - configure and start the ipl cpu only */
s390_ipl_prepare_cpu(ipl_cpu);
-s390_cpu_set_state(CPU_STATE_OPERATING, ipl_cpu);
+s390_cpu_set_state(S390_CPU_STATE_OPERATING, ipl_cpu);
}
static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
diff --git a/qapi-schema.json b/qapi-schema.json
index 5c06745..66e0927 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -410,10 +410,12 @@
# An enumeration of cpu types that enable additional information during
# @query-cpus.
#
+# @s390: since 2.12
+#
# Since: 2.6
##
{ 'enum': 'CpuInfoArch',
- 'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 'other' ] }
+ 'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 's390', 'other' ] }
##
# @CpuInfo:
@@ -452,6 +454,7 @@
'ppc': 'CpuInfoPPC',
'mips': 'CpuInfoMIPS',
'tricore': 'CpuInfoTricore',
+'s390': 'CpuInfoS390',
'other': 'CpuInfoOther' } }
##
@@ -522,6 +525,29 @@
{ 'struct': 'CpuInfoOther', 'data': { } }
##
+# @CpuS390State:
+#
+# An enumeration of cpu states that can be assumed by a virtual
+# S390 CPU
+#
+# Since: 2.12
+##
+{ 'enum': 'CpuS390State',
+ 'prefix': 'S390_CPU_STATE',
+ 'data': [ 'uninitialized', 'stopped', 'check-stop', 'operating', 'load' ] }
+
+##
+# @CpuInfoS390:
+#
+# Additional information about a virtual S390 CPU
+#
+# @cpu-state: the virtual CPU's state
+#
+# Since: 2.12
+##
+{ 'struct': 'CpuInfoS390', 'data': { 'cpu-state': 'CpuS390State' } }
+
+##
# @query-cpus:
#
# Returns a list of information about each virtual CPU.
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index d2e6b9f..4621eb4 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -58,8 +58,8 @@ static bool s390_cpu_has_work(CPUState *cs)
S390CPU *cpu = S390_CPU(cs);
/* STOPPED cpus can never wake up */
-if (s390_cpu_get_state(cpu) != CPU_STATE_LOAD &&
-s390_cpu_get_state(cpu) != CPU_STATE_OPERATING) {
+if (s390_cpu_get_state(cpu) != S390_CPU_STATE_LOAD &&
+s390_cpu_get_state(