Skip to content

Commit

Permalink
target/s390x/cpu topology: handle STSI(15) and build the SYSIB
Browse files Browse the repository at this point in the history
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@linux.ibm.com>
Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Message-ID: <20231016183925.2384704-5-nsg@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
  • Loading branch information
Pierre Morel authored and huth committed Oct 20, 2023
1 parent c809bbc commit f4f54b5
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 2 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,7 @@ M: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
S: Supported
F: include/hw/s390x/cpu-topology.h
F: hw/s390x/cpu-topology.c
F: target/s390x/kvm/stsi-topology.c

X86 Machines
------------
Expand Down
2 changes: 2 additions & 0 deletions hw/s390x/cpu-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@
* s390_topology is used to keep the topology information.
* .cores_per_socket: tracks information on the count of cores
* per socket.
* .polarization: tracks machine polarization.
*/
S390Topology s390_topology = {
/* will be initialized after the CPU model is realized */
.cores_per_socket = NULL,
.polarization = S390_CPU_POLARIZATION_HORIZONTAL,
};

/**
Expand Down
23 changes: 23 additions & 0 deletions include/hw/s390x/cpu-topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,33 @@
#include "hw/boards.h"
#include "qapi/qapi-types-machine-target.h"

#define S390_TOPOLOGY_CPU_IFL 0x03

typedef struct S390TopologyId {
uint8_t sentinel;
uint8_t drawer;
uint8_t book;
uint8_t socket;
uint8_t type;
uint8_t vertical:1;
uint8_t entitlement:2;
uint8_t dedicated;
uint8_t origin;
} S390TopologyId;

typedef struct S390TopologyEntry {
QTAILQ_ENTRY(S390TopologyEntry) next;
S390TopologyId id;
uint64_t mask;
} S390TopologyEntry;

typedef struct S390Topology {
uint8_t *cores_per_socket;
CpuS390Polarization polarization;
} S390Topology;

typedef QTAILQ_HEAD(, S390TopologyEntry) S390TopologyList;

#ifdef CONFIG_KVM
bool s390_has_topology(void);
void s390_topology_setup_cpu(MachineState *ms, S390CPU *cpu, Error **errp);
Expand Down
1 change: 1 addition & 0 deletions include/hw/s390x/sclp.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ typedef struct CPUEntry {
} QEMU_PACKED CPUEntry;

#define SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET 128
#define SCLP_READ_SCP_INFO_MNEST 2
typedef struct ReadInfo {
SCCBHeader h;
uint16_t rnmax;
Expand Down
14 changes: 14 additions & 0 deletions qapi/machine-target.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.2
##
{ 'enum': 'CpuS390Polarization',
'prefix': 'S390_CPU_POLARIZATION',
'data': [ 'horizontal', 'vertical' ],
'if': 'TARGET_S390X'
}
75 changes: 75 additions & 0 deletions target/s390x/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,16 +570,91 @@ typedef struct SysIB_322 {
} SysIB_322;
QEMU_BUILD_BUG_ON(sizeof(SysIB_322) != 4096);

/*
* Topology Magnitude fields (MAG) indicates the maximum number of
* topology list entries (TLE) at the corresponding nesting level.
*/
#define S390_TOPOLOGY_MAG 6
#define S390_TOPOLOGY_MAG6 0
#define S390_TOPOLOGY_MAG5 1
#define S390_TOPOLOGY_MAG4 2
#define S390_TOPOLOGY_MAG3 3
#define S390_TOPOLOGY_MAG2 4
#define S390_TOPOLOGY_MAG1 5
/* Configuration topology */
typedef struct SysIB_151x {
uint8_t reserved0[2];
uint16_t length;
uint8_t mag[S390_TOPOLOGY_MAG];
uint8_t reserved1;
uint8_t mnest;
uint32_t reserved2;
char tle[];
} SysIB_151x;
QEMU_BUILD_BUG_ON(sizeof(SysIB_151x) != 16);

typedef union SysIB {
SysIB_111 sysib_111;
SysIB_121 sysib_121;
SysIB_122 sysib_122;
SysIB_221 sysib_221;
SysIB_222 sysib_222;
SysIB_322 sysib_322;
SysIB_151x sysib_151x;
} SysIB;
QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096);

/*
* CPU Topology List provided by STSI with fc=15 provides a list
* of two different Topology List Entries (TLE) types to specify
* the topology hierarchy.
*
* - Container Topology List Entry
* Defines a container to contain other Topology List Entries
* of any type, nested containers or CPU.
* - CPU Topology List Entry
* Specifies the CPUs position, type, entitlement and polarization
* of the CPUs contained in the last container TLE.
*
* There can be theoretically up to five levels of containers, QEMU
* uses only three levels, the drawer's, book's and socket's level.
*
* A container with a nesting level (NL) greater than 1 can only
* contain another container of nesting level NL-1.
*
* A container of nesting level 1 (socket), contains as many CPU TLE
* as needed to describe the position and qualities of all CPUs inside
* the container.
* The qualities of a CPU are polarization, entitlement and type.
*
* The CPU TLE defines the position of the CPUs of identical qualities
* using a 64bits mask which first bit has its offset defined by
* the CPU address origin field of the CPU TLE like in:
* CPU address = origin * 64 + bit position within the mask
*/
/* Container type Topology List Entry */
typedef struct SYSIBContainerListEntry {
uint8_t nl;
uint8_t reserved[6];
uint8_t id;
} SYSIBContainerListEntry;
QEMU_BUILD_BUG_ON(sizeof(SYSIBContainerListEntry) != 8);

/* CPU type Topology List Entry */
typedef struct SysIBCPUListEntry {
uint8_t nl;
uint8_t reserved0[3];
#define SYSIB_TLE_POLARITY_MASK 0x03
#define SYSIB_TLE_DEDICATED 0x04
uint8_t flags;
uint8_t type;
uint16_t origin;
uint64_t mask;
} SysIBCPUListEntry;
QEMU_BUILD_BUG_ON(sizeof(SysIBCPUListEntry) != 16);

void insert_stsi_15_1_x(S390CPU *cpu, int sel2, uint64_t addr, uint8_t ar, uintptr_t ra);

/* MMU defines */
#define ASCE_ORIGIN (~0xfffULL) /* segment table origin */
#define ASCE_SUBSPACE 0x200 /* subspace group control */
Expand Down
5 changes: 4 additions & 1 deletion target/s390x/kvm/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1911,9 +1911,12 @@ static int handle_stsi(S390CPU *cpu)
if (run->s390_stsi.sel1 != 2 || run->s390_stsi.sel2 != 2) {
return 0;
}
/* Only sysib 3.2.2 needs post-handling for now. */
insert_stsi_3_2_2(cpu, run->s390_stsi.addr, run->s390_stsi.ar);
return 0;
case 15:
insert_stsi_15_1_x(cpu, run->s390_stsi.sel2, run->s390_stsi.addr,
run->s390_stsi.ar, RA_IGNORED);
return 0;
default:
return 0;
}
Expand Down
3 changes: 2 additions & 1 deletion target/s390x/kvm/meson.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

s390x_ss.add(when: 'CONFIG_KVM', if_true: files(
'pv.c',
'kvm.c'
'kvm.c',
'stsi-topology.c'
), if_false: files(
'stubs.c'
))
Expand Down

0 comments on commit f4f54b5

Please sign in to comment.