On Fri, 2023-06-30 at 11:17 +0200, Pierre Morel wrote: > On interception of STSI(15.1.x) the System Information Block > (SYSIB) is built from the list of pre-ordered topology entries. > > Signed-off-by: Pierre Morel <pmorel@xxxxxxxxxxxxx> > --- > MAINTAINERS | 1 + > qapi/machine-target.json | 14 ++ > include/hw/s390x/cpu-topology.h | 25 +++ > include/hw/s390x/sclp.h | 1 + > target/s390x/cpu.h | 76 ++++++++ > hw/s390x/cpu-topology.c | 4 +- > target/s390x/kvm/kvm.c | 5 +- > target/s390x/kvm/stsi-topology.c | 310 +++++++++++++++++++++++++++++++ > target/s390x/kvm/meson.build | 3 +- > 9 files changed, 436 insertions(+), 3 deletions(-) > create mode 100644 target/s390x/kvm/stsi-topology.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 0b03ac5a9b..b8d3e8815c 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1702,6 +1702,7 @@ M: Pierre Morel <pmorel@xxxxxxxxxxxxx> > S: Supported > F: include/hw/s390x/cpu-topology.h > F: hw/s390x/cpu-topology.c > +F: target/s390x/kvm/stsi-topology.c > > X86 Machines > ------------ > diff --git a/qapi/machine-target.json b/qapi/machine-target.json > index 3362f8dc3f..8ea4834e63 100644 > --- a/qapi/machine-target.json > +++ b/qapi/machine-target.json > @@ -361,3 +361,17 @@ > 'TARGET_MIPS', > 'TARGET_LOONGARCH64', > 'TARGET_RISCV' ] } } > + > +## > +# @CpuS390Polarization: > +# > +# An enumeration of cpu polarization that can be assumed by a virtual > +# S390 CPU > +# > +# Since: 8.1 > +## > +{ 'enum': 'CpuS390Polarization', > + 'prefix': 'S390_CPU_POLARIZATION', > + 'data': [ 'horizontal', 'vertical' ], > + 'if': { 'all': [ 'TARGET_S390X' , 'CONFIG_KVM' ] } > +} > diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h > index 9164ac00a7..193b33a2fc 100644 > --- a/include/hw/s390x/cpu-topology.h > +++ b/include/hw/s390x/cpu-topology.h > @@ -15,10 +15,35 @@ > #include "hw/boards.h" > #include "qapi/qapi-types-machine-target.h" > > +#define S390_TOPOLOGY_CPU_IFL 0x03 > + > +typedef union s390_topology_id { > + uint64_t id; > + struct { > + uint8_t sentinel; > + uint8_t drawer; > + uint8_t book; > + uint8_t socket; > + uint8_t dedicated; > + uint8_t entitlement; > + uint8_t type; > + uint8_t origin; The order here is not quite right according to the PoP. Type should be higher, after socket, such that all cpus of the same type in a socket are stored as a block. Also entitlement and dedication need to be inverted, e.g such that dedicated cpus are shown before non dedicated ones. > + }; > +} s390_topology_id; > + [...] > +/** > + * s390_topology_empty_list: > + * > + * Clear all entries in the S390Topology list except the sentinel. The comment is out of date. > + */ > +static void s390_topology_empty_list(S390TopologyList *topology_list) > +{ > + S390TopologyEntry *entry = NULL; > + S390TopologyEntry *tmp = NULL; > + > + QTAILQ_FOREACH_SAFE(entry, topology_list, next, tmp) { > + QTAILQ_REMOVE(topology_list, entry, next); > + g_free(entry); > + } > +} > + > +/** > + * insert_stsi_15_1_x: > + * cpu: the CPU doing the call for which we set CC > + * sel2: the selector 2, containing the nested level > + * addr: Guest logical address of the guest SysIB > + * ar: the access register number > + * > + * Create a list head for the Topology entries and initialize it. > + * Insert the first entry as a sentinelle. > + * > + * Emulate STSI 15.1.x, that is, perform all necessary checks and > + * fill the SYSIB. > + * In case the topology description is too long to fit into the SYSIB, > + * set CC=3 and abort without writing the SYSIB. > + */ > +void insert_stsi_15_1_x(S390CPU *cpu, int sel2, uint64_t addr, uint8_t ar) > +{ > + S390TopologyList topology_list; > + S390TopologyEntry *entry; > + SysIB sysib = {0}; > + int length; > + > + if (!s390_has_topology() || sel2 < 2 || sel2 > SCLP_READ_SCP_INFO_MNEST) { > + setcc(cpu, 3); > + return; > + } > + > + QTAILQ_INIT(&topology_list); > + entry = g_malloc0(sizeof(S390TopologyEntry)); > + entry->id.sentinel = 0xff; > + QTAILQ_INSERT_HEAD(&topology_list, entry, next); > + > + s390_topology_fill_list_sorted(&topology_list); > + > + length = setup_stsi(&topology_list, &sysib.sysib_151x, sel2); > + > + if (!length) { > + setcc(cpu, 3); > + return; > + } > + > + sysib.sysib_151x.length = cpu_to_be16(length); > + s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, length); > + setcc(cpu, 0); > + > + s390_topology_empty_list(&topology_list); > +} > diff --git a/target/s390x/kvm/meson.build b/target/s390x/kvm/meson.build > index 37253f75bf..bcf014ba87 100644 > --- a/target/s390x/kvm/meson.build > +++ b/target/s390x/kvm/meson.build > @@ -1,6 +1,7 @@ > > s390x_ss.add(when: 'CONFIG_KVM', if_true: files( > - 'kvm.c' > + 'kvm.c', > + 'stsi-topology.c' > ), if_false: files( > 'stubs.c' > ))