Commit 9d0306df authored by Viktor Mihajlovski's avatar Viktor Mihajlovski Committed by Cornelia Huck
Browse files

qmp: expose s390-specific CPU info



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: default avatarViktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Reviewed-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Message-Id: <1518797321-28356-2-git-send-email-mihajlov@linux.vnet.ibm.com>
Reviewed-by: default avatarCornelia Huck <cohuck@redhat.com>
Signed-off-by: default avatarCornelia Huck <cohuck@redhat.com>
parent 21fc97c5
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2100,6 +2100,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);
@@ -2127,6 +2130,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
+2 −2
Original line number Diff line number Diff line
@@ -192,8 +192,8 @@ static void qemu_s390_flic_notify(uint32_t type)
        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;
        }

+1 −1
Original line number Diff line number Diff line
@@ -368,7 +368,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,
+27 −1
Original line number Diff line number Diff line
@@ -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' } }

##
@@ -521,6 +524,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:
#
+12 −12
Original line number Diff line number Diff line
@@ -61,8 +61,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(cpu) != S390_CPU_STATE_OPERATING) {
        return false;
    }

@@ -80,7 +80,7 @@ static void s390_cpu_load_normal(CPUState *s)
    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

@@ -95,7 +95,7 @@ static void s390_cpu_reset(CPUState *s)
    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() */
@@ -138,7 +138,7 @@ static void s390_cpu_full_reset(CPUState *s)

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

@@ -292,7 +292,7 @@ static void s390_cpu_initfn(Object *obj)
    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
}

@@ -320,8 +320,8 @@ static unsigned s390_count_running_cpus(void)

    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++;
            }
@@ -360,13 +360,13 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
    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.
Loading