target/s390x: use "core-id" for cpu number/address/id handling

Some time ago we discussed that using "id" as property name is not the
right thing to do, as it is a reserved property for other devices and
will not work with device_add.

Switch to the term "core-id" instead, and use it as an equivalent to
"CPU address" mentioned in the PoP. There is no such thing as cpu number,
so rename env.cpu_num to env.core_id. We use "core-id" as this is the
common term to use for device_add later on (x86 and ppc).

We can get rid of cpu->id now. Keep cpu_index and env->core_id in sync.
cpu_index was already implicitly used by e.g. cpu_exists(), so keeping
both in sync seems to be the right thing to do.

cpu_index will now no longer automatically get set via
cpu_exec_realizefn(). For now, we were lucky that both implicitly stayed
in sync.

Our new cpu property "core-id" can be a static property. Range checks can
be avoided by using the correct type and the "setting after realized"
check is done implicitly.

device_add will later need the reserved "id" property. Hotplugging a CPU
on s390x will then be: "device_add host-s390-cpu,id=cpu2,core-id=2".

Reviewed-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20170913132417.24384-14-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
David Hildenbrand 2017-09-13 15:24:08 +02:00 committed by Cornelia Huck
parent 88556edd74
commit ca5c1457d6
8 changed files with 30 additions and 66 deletions

View File

@ -312,7 +312,7 @@ static void s390_cpu_plug(HotplugHandler *hotplug_dev,
S390CPU *cpu = S390_CPU(dev);
CPUState *cs = CPU(dev);
name = g_strdup_printf("cpu[%i]", cpu->env.cpu_num);
name = g_strdup_printf("cpu[%i]", cpu->env.core_id);
object_property_set_link(OBJECT(hotplug_dev), OBJECT(cs), name,
errp);
g_free(name);

View File

@ -36,6 +36,7 @@
#include "trace.h"
#include "qapi/visitor.h"
#include "exec/exec-all.h"
#include "hw/qdev-properties.h"
#ifndef CONFIG_USER_ONLY
#include "hw/hw.h"
#include "sysemu/arch_init.h"
@ -189,28 +190,31 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
}
#if !defined(CONFIG_USER_ONLY)
if (cpu->id >= max_cpus) {
error_setg(&err, "Unable to add CPU: %" PRIi64
", max allowed: %d", cpu->id, max_cpus - 1);
if (cpu->env.core_id >= max_cpus) {
error_setg(&err, "Unable to add CPU with core-id: %" PRIu32
", maximum core-id: %d", cpu->env.core_id,
max_cpus - 1);
goto out;
}
#else
/* implicitly set for linux-user only */
cpu->id = scc->next_cpu_id;
cpu->env.core_id = scc->next_cpu_id;
#endif
if (cpu_exists(cpu->id)) {
error_setg(&err, "Unable to add CPU: %" PRIi64
", it already exists", cpu->id);
if (cpu_exists(cpu->env.core_id)) {
error_setg(&err, "Unable to add CPU with core-id: %" PRIu32
", it already exists", cpu->env.core_id);
goto out;
}
if (cpu->id != scc->next_cpu_id) {
error_setg(&err, "Unable to add CPU: %" PRIi64
", The next available id is %" PRIi64, cpu->id,
if (cpu->env.core_id != scc->next_cpu_id) {
error_setg(&err, "Unable to add CPU with core-id: %" PRIu32
", the next available core-id is %" PRIi64, cpu->env.core_id,
scc->next_cpu_id);
goto out;
}
/* sync cs->cpu_index and env->core_id. The latter is needed for TCG. */
cs->cpu_index = env->core_id;
cpu_exec_realizefn(cs, &err);
if (err != NULL) {
goto out;
@ -220,7 +224,6 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
#if !defined(CONFIG_USER_ONLY)
qemu_register_reset(s390_cpu_machine_reset_cb, cpu);
#endif
env->cpu_num = cpu->id;
s390_cpu_gdb_init(cs);
qemu_init_vcpu(cs);
#if !defined(CONFIG_USER_ONLY)
@ -241,45 +244,6 @@ out:
error_propagate(errp, err);
}
static void s390x_cpu_get_id(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
S390CPU *cpu = S390_CPU(obj);
int64_t value = cpu->id;
visit_type_int(v, name, &value, errp);
}
static void s390x_cpu_set_id(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
S390CPU *cpu = S390_CPU(obj);
DeviceState *dev = DEVICE(obj);
const int64_t min = 0;
const int64_t max = UINT32_MAX;
Error *err = NULL;
int64_t value;
if (dev->realized) {
error_setg(errp, "Attempt to set property '%s' on '%s' after "
"it was realized", name, object_get_typename(obj));
return;
}
visit_type_int(v, name, &value, &err);
if (err) {
error_propagate(errp, err);
return;
}
if (value < min || value > max) {
error_setg(errp, "Property %s.%s doesn't take value %" PRId64
" (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
object_get_typename(obj), name, value, min, max);
return;
}
cpu->id = value;
}
static void s390_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
@ -293,8 +257,6 @@ static void s390_cpu_initfn(Object *obj)
cs->env_ptr = env;
cs->halted = 1;
cs->exception_index = EXCP_HLT;
object_property_add(OBJECT(cpu), "id", "int64_t", s390x_cpu_get_id,
s390x_cpu_set_id, NULL, NULL, NULL);
s390_cpu_model_register_props(obj);
#if !defined(CONFIG_USER_ONLY)
qemu_get_timedate(&tm, 0);
@ -491,6 +453,11 @@ static gchar *s390_gdb_arch_name(CPUState *cs)
return g_strdup("s390:64-bit");
}
static Property s390x_cpu_properties[] = {
DEFINE_PROP_UINT32("core-id", S390CPU, env.core_id, 0),
DEFINE_PROP_END_OF_LIST()
};
static void s390_cpu_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *scc = S390_CPU_CLASS(oc);
@ -500,6 +467,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
scc->next_cpu_id = 0;
scc->parent_realize = dc->realize;
dc->realize = s390_cpu_realizefn;
dc->props = s390x_cpu_properties;
scc->parent_reset = cc->reset;
#if !defined(CONFIG_USER_ONLY)

View File

@ -150,7 +150,7 @@ struct CPUS390XState {
CPU_COMMON
uint32_t cpu_num;
uint32_t core_id; /* PoP "CPU address", same as cpu_index */
uint64_t cpuid;
uint64_t tod_offset;
@ -194,7 +194,6 @@ struct S390CPU {
/*< public >*/
CPUS390XState env;
int64_t id;
S390CPUModel *model;
/* needed for live migration */
void *irqstate;
@ -690,7 +689,7 @@ const char *s390_default_cpu_model_name(void);
/* helper.c */
#define cpu_init(cpu_model) cpu_generic_init(TYPE_S390_CPU, cpu_model)
S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp);
S390CPU *s390x_new_cpu(const char *cpu_model, uint32_t core_id, Error **errp);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */

View File

@ -915,7 +915,7 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model);
if (tcg_enabled()) {
/* basic mode, write the cpu address into the first 4 bit of the ID */
cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.cpu_num);
cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.core_id);
}
}

View File

@ -250,7 +250,7 @@ static void do_ext_interrupt(CPUS390XState *env)
lowcore->ext_params2 = cpu_to_be64(q->param64);
lowcore->external_old_psw.mask = cpu_to_be64(get_psw_mask(env));
lowcore->external_old_psw.addr = cpu_to_be64(env->psw.addr);
lowcore->cpu_addr = cpu_to_be16(env->cpu_num | VIRTIO_SUBCODE_64);
lowcore->cpu_addr = cpu_to_be16(env->core_id | VIRTIO_SUBCODE_64);
mask = be64_to_cpu(lowcore->external_new_psw.mask);
addr = be64_to_cpu(lowcore->external_new_psw.addr);

View File

@ -104,7 +104,7 @@ S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp)
return S390_CPU(CPU(object_new(typename)));
}
S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp)
S390CPU *s390x_new_cpu(const char *cpu_model, uint32_t core_id, Error **errp)
{
S390CPU *cpu;
Error *err = NULL;
@ -114,7 +114,7 @@ S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp)
goto out;
}
object_property_set_int(OBJECT(cpu), id, "id", &err);
object_property_set_int(OBJECT(cpu), core_id, "core-id", &err);
if (err != NULL) {
goto out;
}

View File

@ -232,7 +232,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0,
/* XXX make different for different CPUs? */
ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
ebcdic_put(sysib.plant, "QEMU", 4);
stw_p(&sysib.cpu_addr, env->cpu_num);
stw_p(&sysib.cpu_addr, env->core_id);
cpu_physical_memory_write(a0, &sysib, sizeof(sysib));
} else if ((sel1 == 2) && (sel2 == 2)) {
/* Basic Machine CPUs */
@ -260,7 +260,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0,
/* XXX make different for different CPUs? */
ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
ebcdic_put(sysib.plant, "QEMU", 4);
stw_p(&sysib.cpu_addr, env->cpu_num);
stw_p(&sysib.cpu_addr, env->core_id);
stw_p(&sysib.cpu_id, 0);
cpu_physical_memory_write(a0, &sysib, sizeof(sysib));
} else if ((sel1 == 2) && (sel2 == 2)) {

View File

@ -3823,10 +3823,7 @@ static ExitStatus op_ssm(DisasContext *s, DisasOps *o)
static ExitStatus op_stap(DisasContext *s, DisasOps *o)
{
check_privileged(s);
/* ??? Surely cpu address != cpu number. In any case the previous
version of this stored more than the required half-word, so it
is unlikely this has ever been tested. */
tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, cpu_num));
tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, core_id));
return NO_EXIT;
}