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}
]
This change doesn't add the s390-specific data to HMP 'info cpus'.
A follow-on patch will remove all architecture specific information
from there.
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <
1518797321-28356-2-git-send-email-mihajlov@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
#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);
#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
cs->interrupt_request |= CPU_INTERRUPT_HARD;
/* ignore CPUs that are not sleeping */
- if (s390_cpu_get_state(cpu) != CPU_STATE_OPERATING &&
- s390_cpu_get_state(cpu) != CPU_STATE_LOAD) {
+ if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING &&
+ s390_cpu_get_state(cpu) != S390_CPU_STATE_LOAD) {
continue;
}
/* 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,
# 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:
'ppc': 'CpuInfoPPC',
'mips': 'CpuInfoMIPS',
'tricore': 'CpuInfoTricore',
+ 's390': 'CpuInfoS390',
'other': 'CpuInfoOther' } }
##
##
{ '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:
#
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(cpu) != S390_CPU_STATE_OPERATING) {
return false;
}
S390CPU *cpu = S390_CPU(s);
cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR;
cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64;
- s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
+ s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
}
#endif
env->bpbc = false;
scc->parent_reset(s);
cpu->env.sigp_order = 0;
- s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
+ s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
}
/* S390CPUClass::initial_reset() */
scc->parent_reset(s);
cpu->env.sigp_order = 0;
- s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
+ s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
memset(env, 0, offsetof(CPUS390XState, end_reset_fields));
env->tod_basetime = 0;
env->tod_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
env->cpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
- s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
+ s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
#endif
}
CPU_FOREACH(cpu) {
uint8_t state = S390_CPU(cpu)->env.cpu_state;
- if (state == CPU_STATE_OPERATING ||
- state == CPU_STATE_LOAD) {
+ if (state == S390_CPU_STATE_OPERATING ||
+ state == S390_CPU_STATE_LOAD) {
if (!disabled_wait(cpu)) {
nr_running++;
}
trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state);
switch (cpu_state) {
- case CPU_STATE_STOPPED:
- case CPU_STATE_CHECK_STOP:
+ case S390_CPU_STATE_STOPPED:
+ case S390_CPU_STATE_CHECK_STOP:
/* halt the cpu for common infrastructure */
s390_cpu_halt(cpu);
break;
- case CPU_STATE_OPERATING:
- case CPU_STATE_LOAD:
+ case S390_CPU_STATE_OPERATING:
+ case S390_CPU_STATE_LOAD:
/*
* Starting a CPU with a PSW WAIT bit set:
* KVM: handles this internally and triggers another WAIT exit.
* architectures, there is a difference between a halt and a stop on s390.
* If all cpus are either stopped (including check stop) or in the disabled
* wait state, the vm can be shut down.
+ * The acceptable cpu_state values are defined in the CpuInfoS390State
+ * enum.
*/
-#define CPU_STATE_UNINITIALIZED 0x00
-#define CPU_STATE_STOPPED 0x01
-#define CPU_STATE_CHECK_STOP 0x02
-#define CPU_STATE_OPERATING 0x03
-#define CPU_STATE_LOAD 0x04
uint8_t cpu_state;
/* currently processed sigp order */
}
switch (cpu_state) {
- case CPU_STATE_STOPPED:
+ case S390_CPU_STATE_STOPPED:
mp_state.mp_state = KVM_MP_STATE_STOPPED;
break;
- case CPU_STATE_CHECK_STOP:
+ case S390_CPU_STATE_CHECK_STOP:
mp_state.mp_state = KVM_MP_STATE_CHECK_STOP;
break;
- case CPU_STATE_OPERATING:
+ case S390_CPU_STATE_OPERATING:
mp_state.mp_state = KVM_MP_STATE_OPERATING;
break;
- case CPU_STATE_LOAD:
+ case S390_CPU_STATE_LOAD:
mp_state.mp_state = KVM_MP_STATE_LOAD;
break;
default:
}
/* sensing without locks is racy, but it's the same for real hw */
- if (state != CPU_STATE_STOPPED && !ext_call) {
+ if (state != S390_CPU_STATE_STOPPED && !ext_call) {
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
} else {
if (ext_call) {
status |= SIGP_STAT_EXT_CALL_PENDING;
}
- if (state == CPU_STATE_STOPPED) {
+ if (state == S390_CPU_STATE_STOPPED) {
status |= SIGP_STAT_STOPPED;
}
set_sigp_status(si, status);
S390CPU *cpu = S390_CPU(cs);
SigpInfo *si = arg.host_ptr;
- if (s390_cpu_get_state(cpu) != CPU_STATE_STOPPED) {
+ if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
return;
}
- s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
+ s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}
S390CPU *cpu = S390_CPU(cs);
SigpInfo *si = arg.host_ptr;
- if (s390_cpu_get_state(cpu) != CPU_STATE_OPERATING) {
+ if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING) {
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
return;
}
/* disabled wait - sleeping in user space */
if (cs->halted) {
- s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
+ s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
} else {
/* execute the stop function */
cpu->env.sigp_order = SIGP_STOP;
SigpInfo *si = arg.host_ptr;
/* disabled wait - sleeping in user space */
- if (s390_cpu_get_state(cpu) == CPU_STATE_OPERATING && cs->halted) {
- s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
+ if (s390_cpu_get_state(cpu) == S390_CPU_STATE_OPERATING && cs->halted) {
+ s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
}
switch (s390_cpu_get_state(cpu)) {
- case CPU_STATE_OPERATING:
+ case S390_CPU_STATE_OPERATING:
cpu->env.sigp_order = SIGP_STOP_STORE_STATUS;
cpu_inject_stop(cpu);
/* store will be performed in do_stop_interrup() */
break;
- case CPU_STATE_STOPPED:
+ case S390_CPU_STATE_STOPPED:
/* already stopped, just store the status */
cpu_synchronize_state(cs);
s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
uint32_t address = si->param & 0x7ffffe00u;
/* cpu has to be stopped */
- if (s390_cpu_get_state(cpu) != CPU_STATE_STOPPED) {
+ if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
return;
}
}
/* cpu has to be stopped */
- if (s390_cpu_get_state(cpu) != CPU_STATE_STOPPED) {
+ if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
return;
}
SigpInfo *si = arg.host_ptr;
switch (s390_cpu_get_state(cpu)) {
- case CPU_STATE_STOPPED:
+ case S390_CPU_STATE_STOPPED:
/* the restart irq has to be delivered prior to any other pending irq */
cpu_synchronize_state(cs);
/*
* Set OPERATING (and unhalting) before loading the restart PSW.
* load_psw() will then properly halt the CPU again if necessary (TCG).
*/
- s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
+ s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
do_restart_interrupt(&cpu->env);
break;
- case CPU_STATE_OPERATING:
+ case S390_CPU_STATE_OPERATING:
cpu_inject_restart(cpu);
break;
}
}
/* cpu has to be stopped */
- if (s390_cpu_get_state(cpu) != CPU_STATE_STOPPED) {
+ if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
return;
}
p_asn = dst_cpu->env.cregs[4] & 0xffff; /* Primary ASN */
s_asn = dst_cpu->env.cregs[3] & 0xffff; /* Secondary ASN */
- if (s390_cpu_get_state(dst_cpu) != CPU_STATE_STOPPED ||
+ if (s390_cpu_get_state(dst_cpu) != S390_CPU_STATE_STOPPED ||
(psw_mask & psw_int_mask) != psw_int_mask ||
(idle && psw_addr != 0) ||
(!idle && (asn == p_asn || asn == s_asn))) {
if (cur_cpu == cpu) {
continue;
}
- if (s390_cpu_get_state(cur_cpu) != CPU_STATE_STOPPED) {
+ if (s390_cpu_get_state(cur_cpu) != S390_CPU_STATE_STOPPED) {
all_stopped = false;
}
}
{
S390CPU *cpu = s390_env_get_cpu(env);
- if (s390_cpu_set_state(CPU_STATE_STOPPED, cpu) == 0) {
+ if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
}
if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {