Re: [PATCH v10 2/9] s390x/cpu topology: reporting the CPU topology to the guest

2022-11-07 Thread Pierre Morel




On 11/7/22 14:20, Janis Schoetterl-Glausch wrote:

On Fri, 2022-10-28 at 12:00 +0200, Pierre Morel wrote:


On 10/27/22 22:42, Janis Schoetterl-Glausch wrote:

On Wed, 2022-10-12 at 18:21 +0200, Pierre Morel wrote:

The guest can use the STSI instruction to get a buffer filled
with the CPU topology description.

Let us implement the STSI instruction for the basis CPU topology
level, level 2.

Signed-off-by: Pierre Morel 
---
   include/hw/s390x/cpu-topology.h |   3 +
   target/s390x/cpu.h  |  48 ++
   hw/s390x/cpu-topology.c |   8 ++-
   target/s390x/cpu_topology.c | 109 
   target/s390x/kvm/kvm.c  |   6 +-
   target/s390x/meson.build|   1 +
   6 files changed, 172 insertions(+), 3 deletions(-)
   create mode 100644 target/s390x/cpu_topology.c

diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
index 66c171d0bc..61c11db017 100644
--- a/include/hw/s390x/cpu-topology.h
+++ b/include/hw/s390x/cpu-topology.h
@@ -13,6 +13,8 @@
   #include "hw/qdev-core.h"
   #include "qom/object.h"
   
+#define S390_TOPOLOGY_POLARITY_H  0x00

+
   typedef struct S390TopoContainer {
   int active_count;
   } S390TopoContainer;
@@ -29,6 +31,7 @@ struct S390Topology {
   S390TopoContainer *socket;
   S390TopoTLE *tle;
   MachineState *ms;
+QemuMutex topo_mutex;
   };
   
   #define TYPE_S390_CPU_TOPOLOGY "s390-topology"

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7d6d01325b..d604aa9c78 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h


[...]

+
+/* Maxi size of a SYSIB structure is when all CPU are alone in a container */


Max or Maximum.


+#define S390_TOPOLOGY_SYSIB_SIZE (sizeof(SysIB_151x) + 
\
+  S390_MAX_CPUS * (sizeof(SysIBTl_container) + 
\
+   sizeof(SysIBTl_cpu)))


Currently this is 16+248*3*8 == 5968 and will grow with books, drawer support to
16+248*5*8 == 9936 ...

[...]


+
+void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar)
+{
+uint64_t page[S390_TOPOLOGY_SYSIB_SIZE / sizeof(uint64_t)] = {};


... so calling this page is a bit misleading. Also why not make it a char[]?
And maybe use a union for type punning.


OK, what about:

  union {
  char place_holder[S390_TOPOLOGY_SYSIB_SIZE];
  SysIB_151x sysib;
  } buffer QEMU_ALIGNED(8);


I don't think you need the QEMU_ALIGNED since SysIB_151x already has it. Not 
that it hurts to be
explicit. If you declared the tle member as uint64_t[], you should get the 
correct alignment
automatically and can then drop the explicit one.


I find the explicit statement better. Why make it non explicit?


Btw, [] seems to be preferred over [0], at least there is a commit doing a 
conversion:
f7795e4096 ("misc: Replace zero-length arrays with flexible array member 
(automatic)")


OK






+SysIB_151x *sysib = (SysIB_151x *) page;
+int len;
+
+if (s390_is_pv() || !s390_has_topology() ||
+sel2 < 2 || sel2 > S390_TOPOLOGY_MAX_MNEST) {
+setcc(cpu, 3);
+return;
+}
+
+len = setup_stsi(sysib, sel2);


This should now be memory safe, but might be larger than 4k,
the maximum size of the SYSIB. I guess you want to set cc code 3
in this case and return.


I do not find why the SYSIB can not be larger than 4k.
Can you point me to this restriction?


Says so at the top of the description of STSI:

The SYSIB is 4K bytes and must begin at a 4 K-byte
boundary; otherwise, a specification exception may
be recognized.


Right, I guess I can not read.

So I will return CC=3 in case the length is greater than 4K


thanks,
Regards,

Pierre


--
Pierre Morel
IBM Lab Boeblingen



Re: [PATCH v10 2/9] s390x/cpu topology: reporting the CPU topology to the guest

2022-11-07 Thread Janis Schoetterl-Glausch
On Fri, 2022-10-28 at 12:00 +0200, Pierre Morel wrote:
> 
> On 10/27/22 22:42, Janis Schoetterl-Glausch wrote:
> > On Wed, 2022-10-12 at 18:21 +0200, Pierre Morel wrote:
> > > The guest can use the STSI instruction to get a buffer filled
> > > with the CPU topology description.
> > > 
> > > Let us implement the STSI instruction for the basis CPU topology
> > > level, level 2.
> > > 
> > > Signed-off-by: Pierre Morel 
> > > ---
> > >   include/hw/s390x/cpu-topology.h |   3 +
> > >   target/s390x/cpu.h  |  48 ++
> > >   hw/s390x/cpu-topology.c |   8 ++-
> > >   target/s390x/cpu_topology.c | 109 
> > >   target/s390x/kvm/kvm.c  |   6 +-
> > >   target/s390x/meson.build|   1 +
> > >   6 files changed, 172 insertions(+), 3 deletions(-)
> > >   create mode 100644 target/s390x/cpu_topology.c
> > > 
> > > diff --git a/include/hw/s390x/cpu-topology.h 
> > > b/include/hw/s390x/cpu-topology.h
> > > index 66c171d0bc..61c11db017 100644
> > > --- a/include/hw/s390x/cpu-topology.h
> > > +++ b/include/hw/s390x/cpu-topology.h
> > > @@ -13,6 +13,8 @@
> > >   #include "hw/qdev-core.h"
> > >   #include "qom/object.h"
> > >   
> > > +#define S390_TOPOLOGY_POLARITY_H  0x00
> > > +
> > >   typedef struct S390TopoContainer {
> > >   int active_count;
> > >   } S390TopoContainer;
> > > @@ -29,6 +31,7 @@ struct S390Topology {
> > >   S390TopoContainer *socket;
> > >   S390TopoTLE *tle;
> > >   MachineState *ms;
> > > +QemuMutex topo_mutex;
> > >   };
> > >   
> > >   #define TYPE_S390_CPU_TOPOLOGY "s390-topology"
> > > diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> > > index 7d6d01325b..d604aa9c78 100644
> > > --- a/target/s390x/cpu.h
> > > +++ b/target/s390x/cpu.h
> > > 
> > [...]
> > > +
> > > +/* Maxi size of a SYSIB structure is when all CPU are alone in a 
> > > container */
> > 
> > Max or Maximum.
> > 
> > > +#define S390_TOPOLOGY_SYSIB_SIZE (sizeof(SysIB_151x) +   
> > >   \
> > > +  S390_MAX_CPUS * 
> > > (sizeof(SysIBTl_container) + \
> > > +   sizeof(SysIBTl_cpu)))
> > 
> > Currently this is 16+248*3*8 == 5968 and will grow with books, drawer 
> > support to
> > 16+248*5*8 == 9936 ...
> > 
> > [...]
> > > 
> > > +
> > > +void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar)
> > > +{
> > > +uint64_t page[S390_TOPOLOGY_SYSIB_SIZE / sizeof(uint64_t)] = {};
> > 
> > ... so calling this page is a bit misleading. Also why not make it a char[]?
> > And maybe use a union for type punning.
> 
> OK, what about:
> 
>  union {
>  char place_holder[S390_TOPOLOGY_SYSIB_SIZE];
>  SysIB_151x sysib;
>  } buffer QEMU_ALIGNED(8);
> 
I don't think you need the QEMU_ALIGNED since SysIB_151x already has it. Not 
that it hurts to be
explicit. If you declared the tle member as uint64_t[], you should get the 
correct alignment
automatically and can then drop the explicit one.
Btw, [] seems to be preferred over [0], at least there is a commit doing a 
conversion:
f7795e4096 ("misc: Replace zero-length arrays with flexible array member 
(automatic)")
> 
> > 
> > > +SysIB_151x *sysib = (SysIB_151x *) page;
> > > +int len;
> > > +
> > > +if (s390_is_pv() || !s390_has_topology() ||
> > > +sel2 < 2 || sel2 > S390_TOPOLOGY_MAX_MNEST) {
> > > +setcc(cpu, 3);
> > > +return;
> > > +}
> > > +
> > > +len = setup_stsi(sysib, sel2);
> > 
> > This should now be memory safe, but might be larger than 4k,
> > the maximum size of the SYSIB. I guess you want to set cc code 3
> > in this case and return.
> 
> I do not find why the SYSIB can not be larger than 4k.
> Can you point me to this restriction?

Says so at the top of the description of STSI:

The SYSIB is 4K bytes and must begin at a 4 K-byte
boundary; otherwise, a specification exception may
be recognized.

Also the graphics show that it is 1024 words long.
> 
> 
> Regards,
> Pierre
> 




Re: [PATCH v10 2/9] s390x/cpu topology: reporting the CPU topology to the guest

2022-10-28 Thread Pierre Morel




On 10/27/22 22:42, Janis Schoetterl-Glausch wrote:

On Wed, 2022-10-12 at 18:21 +0200, Pierre Morel wrote:

The guest can use the STSI instruction to get a buffer filled
with the CPU topology description.

Let us implement the STSI instruction for the basis CPU topology
level, level 2.

Signed-off-by: Pierre Morel 
---
  include/hw/s390x/cpu-topology.h |   3 +
  target/s390x/cpu.h  |  48 ++
  hw/s390x/cpu-topology.c |   8 ++-
  target/s390x/cpu_topology.c | 109 
  target/s390x/kvm/kvm.c  |   6 +-
  target/s390x/meson.build|   1 +
  6 files changed, 172 insertions(+), 3 deletions(-)
  create mode 100644 target/s390x/cpu_topology.c

diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
index 66c171d0bc..61c11db017 100644
--- a/include/hw/s390x/cpu-topology.h
+++ b/include/hw/s390x/cpu-topology.h
@@ -13,6 +13,8 @@
  #include "hw/qdev-core.h"
  #include "qom/object.h"
  
+#define S390_TOPOLOGY_POLARITY_H  0x00

+
  typedef struct S390TopoContainer {
  int active_count;
  } S390TopoContainer;
@@ -29,6 +31,7 @@ struct S390Topology {
  S390TopoContainer *socket;
  S390TopoTLE *tle;
  MachineState *ms;
+QemuMutex topo_mutex;
  };
  
  #define TYPE_S390_CPU_TOPOLOGY "s390-topology"

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7d6d01325b..d604aa9c78 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h


[...]

+
+/* Maxi size of a SYSIB structure is when all CPU are alone in a container */


Max or Maximum.


+#define S390_TOPOLOGY_SYSIB_SIZE (sizeof(SysIB_151x) + 
\
+  S390_MAX_CPUS * (sizeof(SysIBTl_container) + 
\
+   sizeof(SysIBTl_cpu)))


Currently this is 16+248*3*8 == 5968 and will grow with books, drawer support to
16+248*5*8 == 9936 ...

[...]


+
+void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar)
+{
+uint64_t page[S390_TOPOLOGY_SYSIB_SIZE / sizeof(uint64_t)] = {};


... so calling this page is a bit misleading. Also why not make it a char[]?
And maybe use a union for type punning.


OK, what about:

union {
char place_holder[S390_TOPOLOGY_SYSIB_SIZE];
SysIB_151x sysib;
} buffer QEMU_ALIGNED(8);





+SysIB_151x *sysib = (SysIB_151x *) page;
+int len;
+
+if (s390_is_pv() || !s390_has_topology() ||
+sel2 < 2 || sel2 > S390_TOPOLOGY_MAX_MNEST) {
+setcc(cpu, 3);
+return;
+}
+
+len = setup_stsi(sysib, sel2);


This should now be memory safe, but might be larger than 4k,
the maximum size of the SYSIB. I guess you want to set cc code 3
in this case and return.


I do not find why the SYSIB can not be larger than 4k.
Can you point me to this restriction?


Regards,
Pierre

--
Pierre Morel
IBM Lab Boeblingen



Re: [PATCH v10 2/9] s390x/cpu topology: reporting the CPU topology to the guest

2022-10-27 Thread Janis Schoetterl-Glausch
On Wed, 2022-10-12 at 18:21 +0200, Pierre Morel wrote:
> The guest can use the STSI instruction to get a buffer filled
> with the CPU topology description.
> 
> Let us implement the STSI instruction for the basis CPU topology
> level, level 2.
> 
> Signed-off-by: Pierre Morel 
> ---
>  include/hw/s390x/cpu-topology.h |   3 +
>  target/s390x/cpu.h  |  48 ++
>  hw/s390x/cpu-topology.c |   8 ++-
>  target/s390x/cpu_topology.c | 109 
>  target/s390x/kvm/kvm.c  |   6 +-
>  target/s390x/meson.build|   1 +
>  6 files changed, 172 insertions(+), 3 deletions(-)
>  create mode 100644 target/s390x/cpu_topology.c
> 
> diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
> index 66c171d0bc..61c11db017 100644
> --- a/include/hw/s390x/cpu-topology.h
> +++ b/include/hw/s390x/cpu-topology.h
> @@ -13,6 +13,8 @@
>  #include "hw/qdev-core.h"
>  #include "qom/object.h"
>  
> +#define S390_TOPOLOGY_POLARITY_H  0x00
> +
>  typedef struct S390TopoContainer {
>  int active_count;
>  } S390TopoContainer;
> @@ -29,6 +31,7 @@ struct S390Topology {
>  S390TopoContainer *socket;
>  S390TopoTLE *tle;
>  MachineState *ms;
> +QemuMutex topo_mutex;
>  };
>  
>  #define TYPE_S390_CPU_TOPOLOGY "s390-topology"
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index 7d6d01325b..d604aa9c78 100644
> --- a/target/s390x/cpu.h
> +++ b/target/s390x/cpu.h
> 
[...]
> +
> +/* Maxi size of a SYSIB structure is when all CPU are alone in a container */

Max or Maximum.

> +#define S390_TOPOLOGY_SYSIB_SIZE (sizeof(SysIB_151x) +   
>   \
> +  S390_MAX_CPUS * (sizeof(SysIBTl_container) 
> + \
> +   sizeof(SysIBTl_cpu)))

Currently this is 16+248*3*8 == 5968 and will grow with books, drawer support to
16+248*5*8 == 9936 ...

[...]
> 
> +
> +void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar)
> +{
> +uint64_t page[S390_TOPOLOGY_SYSIB_SIZE / sizeof(uint64_t)] = {};

... so calling this page is a bit misleading. Also why not make it a char[]?
And maybe use a union for type punning.

> +SysIB_151x *sysib = (SysIB_151x *) page;
> +int len;
> +
> +if (s390_is_pv() || !s390_has_topology() ||
> +sel2 < 2 || sel2 > S390_TOPOLOGY_MAX_MNEST) {
> +setcc(cpu, 3);
> +return;
> +}
> +
> +len = setup_stsi(sysib, sel2);

This should now be memory safe, but might be larger than 4k,
the maximum size of the SYSIB. I guess you want to set cc code 3
in this case and return.
> +
> +sysib->length = cpu_to_be16(len);
> +s390_cpu_virt_mem_write(cpu, addr, ar, sysib, len);
> +setcc(cpu, 0);
> +}
> +
> 
[...]




Re: [PATCH v10 2/9] s390x/cpu topology: reporting the CPU topology to the guest

2022-10-27 Thread Pierre Morel




On 10/27/22 10:12, Thomas Huth wrote:

On 12/10/2022 18.21, Pierre Morel wrote:

The guest can use the STSI instruction to get a buffer filled
with the CPU topology description.

Let us implement the STSI instruction for the basis CPU topology
level, level 2.

Signed-off-by: Pierre Morel 
---
  include/hw/s390x/cpu-topology.h |   3 +
  target/s390x/cpu.h  |  48 ++
  hw/s390x/cpu-topology.c |   8 ++-
  target/s390x/cpu_topology.c | 109 
  target/s390x/kvm/kvm.c  |   6 +-
  target/s390x/meson.build    |   1 +
  6 files changed, 172 insertions(+), 3 deletions(-)
  create mode 100644 target/s390x/cpu_topology.c

diff --git a/include/hw/s390x/cpu-topology.h 
b/include/hw/s390x/cpu-topology.h

index 66c171d0bc..61c11db017 100644
--- a/include/hw/s390x/cpu-topology.h
+++ b/include/hw/s390x/cpu-topology.h
@@ -13,6 +13,8 @@
  #include "hw/qdev-core.h"
  #include "qom/object.h"
+#define S390_TOPOLOGY_POLARITY_H  0x00
+
  typedef struct S390TopoContainer {
  int active_count;
  } S390TopoContainer;
@@ -29,6 +31,7 @@ struct S390Topology {
  S390TopoContainer *socket;
  S390TopoTLE *tle;
  MachineState *ms;
+    QemuMutex topo_mutex;
  };
  #define TYPE_S390_CPU_TOPOLOGY "s390-topology"
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7d6d01325b..d604aa9c78 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -565,6 +565,52 @@ typedef union SysIB {
  } SysIB;
  QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096);
+/* CPU type Topology List Entry */
+typedef struct SysIBTl_cpu {
+    uint8_t nl;
+    uint8_t reserved0[3];
+    uint8_t reserved1:5;
+    uint8_t dedicated:1;
+    uint8_t polarity:2;
+    uint8_t type;
+    uint16_t origin;
+    uint64_t mask;
+} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_cpu;
+QEMU_BUILD_BUG_ON(sizeof(SysIBTl_cpu) != 16);
+
+/* Container type Topology List Entry */
+typedef struct SysIBTl_container {
+    uint8_t nl;
+    uint8_t reserved[6];
+    uint8_t id;
+} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_container;
+QEMU_BUILD_BUG_ON(sizeof(SysIBTl_container) != 8);
+
+#define TOPOLOGY_NR_MAG  6
+#define TOPOLOGY_NR_MAG6 0
+#define TOPOLOGY_NR_MAG5 1
+#define TOPOLOGY_NR_MAG4 2
+#define TOPOLOGY_NR_MAG3 3
+#define TOPOLOGY_NR_MAG2 4
+#define TOPOLOGY_NR_MAG1 5
+/* Configuration topology */
+typedef struct SysIB_151x {
+    uint8_t  reserved0[2];
+    uint16_t length;
+    uint8_t  mag[TOPOLOGY_NR_MAG];
+    uint8_t  reserved1;
+    uint8_t  mnest;
+    uint32_t reserved2;
+    char tle[0];
+} QEMU_PACKED QEMU_ALIGNED(8) SysIB_151x;
+QEMU_BUILD_BUG_ON(sizeof(SysIB_151x) != 16);
+
+/* Maxi size of a SYSIB structure is when all CPU are alone in a 
container */
+#define S390_TOPOLOGY_SYSIB_SIZE (sizeof(SysIB_151x) 
+ \
+  S390_MAX_CPUS * 
(sizeof(SysIBTl_container) + \

+   sizeof(SysIBTl_cpu)))
+
+
  /* MMU defines */
  #define ASCE_ORIGIN   (~0xfffULL) /* segment table 
origin */
  #define ASCE_SUBSPACE 0x200   /* subspace group 
control   */

@@ -843,4 +889,6 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
  #include "exec/cpu-all.h"
+void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar);
+
  #endif
diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c
index 42b22a1831..c73cebfe6f 100644
--- a/hw/s390x/cpu-topology.c
+++ b/hw/s390x/cpu-topology.c
@@ -54,8 +54,6 @@ void s390_topology_new_cpu(int core_id)
  return;
  }
-    socket_id = core_id / topo->cpus;
-
  /*
   * At the core level, each CPU is represented by a bit in a 64bit
   * unsigned long which represent the presence of a CPU.
@@ -76,8 +74,13 @@ void s390_topology_new_cpu(int core_id)
  bit %= 64;
  bit = 63 - bit;
+    qemu_mutex_lock(&topo->topo_mutex);
+
+    socket_id = core_id / topo->cpus;
  topo->socket[socket_id].active_count++;
  set_bit(bit, &topo->tle[socket_id].mask[origin]);
+
+    qemu_mutex_unlock(&topo->topo_mutex);
  }
  /**
@@ -101,6 +104,7 @@ static void s390_topology_realize(DeviceState 
*dev, Error **errp)

  topo->tle = g_new0(S390TopoTLE, ms->smp.max_cpus);
  topo->ms = ms;
+    qemu_mutex_init(&topo->topo_mutex);
  }
  /**
diff --git a/target/s390x/cpu_topology.c b/target/s390x/cpu_topology.c
new file mode 100644
index 00..df86a98f23
--- /dev/null
+++ b/target/s390x/cpu_topology.c
@@ -0,0 +1,109 @@
+/*
+ * QEMU S390x CPU Topology
+ *
+ * Copyright IBM Corp. 2022
+ * Author(s): Pierre Morel 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or 
(at

+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/s390x/pv.h"
+#include "hw/sysbus.h"
+#include "hw/s390x/cpu-topology.h"
+#include "hw/s390x/sclp.h"
+
+#define S390_TOPOLOGY_MAX_ST

Re: [PATCH v10 2/9] s390x/cpu topology: reporting the CPU topology to the guest

2022-10-27 Thread Thomas Huth

On 12/10/2022 18.21, Pierre Morel wrote:

The guest can use the STSI instruction to get a buffer filled
with the CPU topology description.

Let us implement the STSI instruction for the basis CPU topology
level, level 2.

Signed-off-by: Pierre Morel 
---
  include/hw/s390x/cpu-topology.h |   3 +
  target/s390x/cpu.h  |  48 ++
  hw/s390x/cpu-topology.c |   8 ++-
  target/s390x/cpu_topology.c | 109 
  target/s390x/kvm/kvm.c  |   6 +-
  target/s390x/meson.build|   1 +
  6 files changed, 172 insertions(+), 3 deletions(-)
  create mode 100644 target/s390x/cpu_topology.c

diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
index 66c171d0bc..61c11db017 100644
--- a/include/hw/s390x/cpu-topology.h
+++ b/include/hw/s390x/cpu-topology.h
@@ -13,6 +13,8 @@
  #include "hw/qdev-core.h"
  #include "qom/object.h"
  
+#define S390_TOPOLOGY_POLARITY_H  0x00

+
  typedef struct S390TopoContainer {
  int active_count;
  } S390TopoContainer;
@@ -29,6 +31,7 @@ struct S390Topology {
  S390TopoContainer *socket;
  S390TopoTLE *tle;
  MachineState *ms;
+QemuMutex topo_mutex;
  };
  
  #define TYPE_S390_CPU_TOPOLOGY "s390-topology"

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7d6d01325b..d604aa9c78 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -565,6 +565,52 @@ typedef union SysIB {
  } SysIB;
  QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096);
  
+/* CPU type Topology List Entry */

+typedef struct SysIBTl_cpu {
+uint8_t nl;
+uint8_t reserved0[3];
+uint8_t reserved1:5;
+uint8_t dedicated:1;
+uint8_t polarity:2;
+uint8_t type;
+uint16_t origin;
+uint64_t mask;
+} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_cpu;
+QEMU_BUILD_BUG_ON(sizeof(SysIBTl_cpu) != 16);
+
+/* Container type Topology List Entry */
+typedef struct SysIBTl_container {
+uint8_t nl;
+uint8_t reserved[6];
+uint8_t id;
+} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_container;
+QEMU_BUILD_BUG_ON(sizeof(SysIBTl_container) != 8);
+
+#define TOPOLOGY_NR_MAG  6
+#define TOPOLOGY_NR_MAG6 0
+#define TOPOLOGY_NR_MAG5 1
+#define TOPOLOGY_NR_MAG4 2
+#define TOPOLOGY_NR_MAG3 3
+#define TOPOLOGY_NR_MAG2 4
+#define TOPOLOGY_NR_MAG1 5
+/* Configuration topology */
+typedef struct SysIB_151x {
+uint8_t  reserved0[2];
+uint16_t length;
+uint8_t  mag[TOPOLOGY_NR_MAG];
+uint8_t  reserved1;
+uint8_t  mnest;
+uint32_t reserved2;
+char tle[0];
+} QEMU_PACKED QEMU_ALIGNED(8) SysIB_151x;
+QEMU_BUILD_BUG_ON(sizeof(SysIB_151x) != 16);
+
+/* Maxi size of a SYSIB structure is when all CPU are alone in a container */
+#define S390_TOPOLOGY_SYSIB_SIZE (sizeof(SysIB_151x) + 
\
+  S390_MAX_CPUS * (sizeof(SysIBTl_container) + 
\
+   sizeof(SysIBTl_cpu)))
+
+
  /* MMU defines */
  #define ASCE_ORIGIN   (~0xfffULL) /* segment table origin 
*/
  #define ASCE_SUBSPACE 0x200   /* subspace group control   
*/
@@ -843,4 +889,6 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
  
  #include "exec/cpu-all.h"
  
+void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar);

+
  #endif
diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c
index 42b22a1831..c73cebfe6f 100644
--- a/hw/s390x/cpu-topology.c
+++ b/hw/s390x/cpu-topology.c
@@ -54,8 +54,6 @@ void s390_topology_new_cpu(int core_id)
  return;
  }
  
-socket_id = core_id / topo->cpus;

-
  /*
   * At the core level, each CPU is represented by a bit in a 64bit
   * unsigned long which represent the presence of a CPU.
@@ -76,8 +74,13 @@ void s390_topology_new_cpu(int core_id)
  bit %= 64;
  bit = 63 - bit;
  
+qemu_mutex_lock(&topo->topo_mutex);

+
+socket_id = core_id / topo->cpus;
  topo->socket[socket_id].active_count++;
  set_bit(bit, &topo->tle[socket_id].mask[origin]);
+
+qemu_mutex_unlock(&topo->topo_mutex);
  }
  
  /**

@@ -101,6 +104,7 @@ static void s390_topology_realize(DeviceState *dev, Error 
**errp)
  topo->tle = g_new0(S390TopoTLE, ms->smp.max_cpus);
  
  topo->ms = ms;

+qemu_mutex_init(&topo->topo_mutex);
  }
  
  /**

diff --git a/target/s390x/cpu_topology.c b/target/s390x/cpu_topology.c
new file mode 100644
index 00..df86a98f23
--- /dev/null
+++ b/target/s390x/cpu_topology.c
@@ -0,0 +1,109 @@
+/*
+ * QEMU S390x CPU Topology
+ *
+ * Copyright IBM Corp. 2022
+ * Author(s): Pierre Morel 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/s390x/pv.h"
+#include "hw/sysbus.h"
+#include "hw/s390x/cpu-topology.h"
+#include "hw/s390x/sclp.h"
+
+#define S390_TOPOLOGY_MAX_STSI_SIZE (S3

Re: [PATCH v10 2/9] s390x/cpu topology: reporting the CPU topology to the guest

2022-10-18 Thread Cédric Le Goater

On 10/12/22 18:21, Pierre Morel wrote:

The guest can use the STSI instruction to get a buffer filled
with the CPU topology description.

Let us implement the STSI instruction for the basis CPU topology
level, level 2.

Signed-off-by: Pierre Morel 
---
  include/hw/s390x/cpu-topology.h |   3 +
  target/s390x/cpu.h  |  48 ++
  hw/s390x/cpu-topology.c |   8 ++-
  target/s390x/cpu_topology.c | 109 
  target/s390x/kvm/kvm.c  |   6 +-
  target/s390x/meson.build|   1 +
  6 files changed, 172 insertions(+), 3 deletions(-)
  create mode 100644 target/s390x/cpu_topology.c

diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
index 66c171d0bc..61c11db017 100644
--- a/include/hw/s390x/cpu-topology.h
+++ b/include/hw/s390x/cpu-topology.h
@@ -13,6 +13,8 @@
  #include "hw/qdev-core.h"
  #include "qom/object.h"
  
+#define S390_TOPOLOGY_POLARITY_H  0x00


The defing looks like a header file guard. I would use

  S390_TOPOLOGY_HORIZONTAL_POLARITY

May be add the 3 vertical ones also, for completeness.


+
  typedef struct S390TopoContainer {
  int active_count;
  } S390TopoContainer;
@@ -29,6 +31,7 @@ struct S390Topology {
  S390TopoContainer *socket;
  S390TopoTLE *tle;
  MachineState *ms;
+QemuMutex topo_mutex;
  };
  
  #define TYPE_S390_CPU_TOPOLOGY "s390-topology"

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7d6d01325b..d604aa9c78 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -565,6 +565,52 @@ typedef union SysIB {
  } SysIB;
  QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096);
  
+/* CPU type Topology List Entry */

+typedef struct SysIBTl_cpu {
+uint8_t nl;
+uint8_t reserved0[3];
+uint8_t reserved1:5;
+uint8_t dedicated:1;
+uint8_t polarity:2;
+uint8_t type;
+uint16_t origin;
+uint64_t mask;
+} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_cpu;
+QEMU_BUILD_BUG_ON(sizeof(SysIBTl_cpu) != 16);
+
+/* Container type Topology List Entry */
+typedef struct SysIBTl_container {
+uint8_t nl;
+uint8_t reserved[6];
+uint8_t id;
+} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_container;
+QEMU_BUILD_BUG_ON(sizeof(SysIBTl_container) != 8);
+
+#define TOPOLOGY_NR_MAG  6
+#define TOPOLOGY_NR_MAG6 0
+#define TOPOLOGY_NR_MAG5 1
+#define TOPOLOGY_NR_MAG4 2
+#define TOPOLOGY_NR_MAG3 3
+#define TOPOLOGY_NR_MAG2 4
+#define TOPOLOGY_NR_MAG1 5


May be add a S390_ prefix. I don't think _NR is important for the
magnitude fields. And these are byte offsets.



+/* Configuration topology */
+typedef struct SysIB_151x {
+uint8_t  reserved0[2];
+uint16_t length;
+uint8_t  mag[TOPOLOGY_NR_MAG];
+uint8_t  reserved1;
+uint8_t  mnest;
+uint32_t reserved2;
+char tle[0];
+} QEMU_PACKED QEMU_ALIGNED(8) SysIB_151x;
+QEMU_BUILD_BUG_ON(sizeof(SysIB_151x) != 16);
+
+/* Maxi size of a SYSIB structure is when all CPU are alone in a container */
+#define S390_TOPOLOGY_SYSIB_SIZE (sizeof(SysIB_151x) + 
\
+  S390_MAX_CPUS * (sizeof(SysIBTl_container) + 
\
+   sizeof(SysIBTl_cpu)))
+
+
  /* MMU defines */
  #define ASCE_ORIGIN   (~0xfffULL) /* segment table origin 
*/
  #define ASCE_SUBSPACE 0x200   /* subspace group control   
*/
@@ -843,4 +889,6 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
  
  #include "exec/cpu-all.h"
  
+void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar);

+
  #endif
diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c
index 42b22a1831..c73cebfe6f 100644
--- a/hw/s390x/cpu-topology.c
+++ b/hw/s390x/cpu-topology.c
@@ -54,8 +54,6 @@ void s390_topology_new_cpu(int core_id)
  return;
  }
  
-socket_id = core_id / topo->cpus;

-
  /*
   * At the core level, each CPU is represented by a bit in a 64bit
   * unsigned long which represent the presence of a CPU.
@@ -76,8 +74,13 @@ void s390_topology_new_cpu(int core_id)
  bit %= 64;
  bit = 63 - bit;
  
+qemu_mutex_lock(&topo->topo_mutex);

+
+socket_id = core_id / topo->cpus;
  topo->socket[socket_id].active_count++;
  set_bit(bit, &topo->tle[socket_id].mask[origin]);
+
+qemu_mutex_unlock(&topo->topo_mutex);
  }
  
  /**

@@ -101,6 +104,7 @@ static void s390_topology_realize(DeviceState *dev, Error 
**errp)
  topo->tle = g_new0(S390TopoTLE, ms->smp.max_cpus);
  
  topo->ms = ms;

+qemu_mutex_init(&topo->topo_mutex);
  }
  
  /**

diff --git a/target/s390x/cpu_topology.c b/target/s390x/cpu_topology.c
new file mode 100644
index 00..df86a98f23
--- /dev/null
+++ b/target/s390x/cpu_topology.c
@@ -0,0 +1,109 @@
+/*
+ * QEMU S390x CPU Topology
+ *
+ * Copyright IBM Corp. 2022


Copyright tag


+ * Author(s): Pierre Morel 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your 

[PATCH v10 2/9] s390x/cpu topology: reporting the CPU topology to the guest

2022-10-12 Thread Pierre Morel
The guest can use the STSI instruction to get a buffer filled
with the CPU topology description.

Let us implement the STSI instruction for the basis CPU topology
level, level 2.

Signed-off-by: Pierre Morel 
---
 include/hw/s390x/cpu-topology.h |   3 +
 target/s390x/cpu.h  |  48 ++
 hw/s390x/cpu-topology.c |   8 ++-
 target/s390x/cpu_topology.c | 109 
 target/s390x/kvm/kvm.c  |   6 +-
 target/s390x/meson.build|   1 +
 6 files changed, 172 insertions(+), 3 deletions(-)
 create mode 100644 target/s390x/cpu_topology.c

diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
index 66c171d0bc..61c11db017 100644
--- a/include/hw/s390x/cpu-topology.h
+++ b/include/hw/s390x/cpu-topology.h
@@ -13,6 +13,8 @@
 #include "hw/qdev-core.h"
 #include "qom/object.h"
 
+#define S390_TOPOLOGY_POLARITY_H  0x00
+
 typedef struct S390TopoContainer {
 int active_count;
 } S390TopoContainer;
@@ -29,6 +31,7 @@ struct S390Topology {
 S390TopoContainer *socket;
 S390TopoTLE *tle;
 MachineState *ms;
+QemuMutex topo_mutex;
 };
 
 #define TYPE_S390_CPU_TOPOLOGY "s390-topology"
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7d6d01325b..d604aa9c78 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -565,6 +565,52 @@ typedef union SysIB {
 } SysIB;
 QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096);
 
+/* CPU type Topology List Entry */
+typedef struct SysIBTl_cpu {
+uint8_t nl;
+uint8_t reserved0[3];
+uint8_t reserved1:5;
+uint8_t dedicated:1;
+uint8_t polarity:2;
+uint8_t type;
+uint16_t origin;
+uint64_t mask;
+} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_cpu;
+QEMU_BUILD_BUG_ON(sizeof(SysIBTl_cpu) != 16);
+
+/* Container type Topology List Entry */
+typedef struct SysIBTl_container {
+uint8_t nl;
+uint8_t reserved[6];
+uint8_t id;
+} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_container;
+QEMU_BUILD_BUG_ON(sizeof(SysIBTl_container) != 8);
+
+#define TOPOLOGY_NR_MAG  6
+#define TOPOLOGY_NR_MAG6 0
+#define TOPOLOGY_NR_MAG5 1
+#define TOPOLOGY_NR_MAG4 2
+#define TOPOLOGY_NR_MAG3 3
+#define TOPOLOGY_NR_MAG2 4
+#define TOPOLOGY_NR_MAG1 5
+/* Configuration topology */
+typedef struct SysIB_151x {
+uint8_t  reserved0[2];
+uint16_t length;
+uint8_t  mag[TOPOLOGY_NR_MAG];
+uint8_t  reserved1;
+uint8_t  mnest;
+uint32_t reserved2;
+char tle[0];
+} QEMU_PACKED QEMU_ALIGNED(8) SysIB_151x;
+QEMU_BUILD_BUG_ON(sizeof(SysIB_151x) != 16);
+
+/* Maxi size of a SYSIB structure is when all CPU are alone in a container */
+#define S390_TOPOLOGY_SYSIB_SIZE (sizeof(SysIB_151x) + 
\
+  S390_MAX_CPUS * (sizeof(SysIBTl_container) + 
\
+   sizeof(SysIBTl_cpu)))
+
+
 /* MMU defines */
 #define ASCE_ORIGIN   (~0xfffULL) /* segment table origin 
*/
 #define ASCE_SUBSPACE 0x200   /* subspace group control   
*/
@@ -843,4 +889,6 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
 
 #include "exec/cpu-all.h"
 
+void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar);
+
 #endif
diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c
index 42b22a1831..c73cebfe6f 100644
--- a/hw/s390x/cpu-topology.c
+++ b/hw/s390x/cpu-topology.c
@@ -54,8 +54,6 @@ void s390_topology_new_cpu(int core_id)
 return;
 }
 
-socket_id = core_id / topo->cpus;
-
 /*
  * At the core level, each CPU is represented by a bit in a 64bit
  * unsigned long which represent the presence of a CPU.
@@ -76,8 +74,13 @@ void s390_topology_new_cpu(int core_id)
 bit %= 64;
 bit = 63 - bit;
 
+qemu_mutex_lock(&topo->topo_mutex);
+
+socket_id = core_id / topo->cpus;
 topo->socket[socket_id].active_count++;
 set_bit(bit, &topo->tle[socket_id].mask[origin]);
+
+qemu_mutex_unlock(&topo->topo_mutex);
 }
 
 /**
@@ -101,6 +104,7 @@ static void s390_topology_realize(DeviceState *dev, Error 
**errp)
 topo->tle = g_new0(S390TopoTLE, ms->smp.max_cpus);
 
 topo->ms = ms;
+qemu_mutex_init(&topo->topo_mutex);
 }
 
 /**
diff --git a/target/s390x/cpu_topology.c b/target/s390x/cpu_topology.c
new file mode 100644
index 00..df86a98f23
--- /dev/null
+++ b/target/s390x/cpu_topology.c
@@ -0,0 +1,109 @@
+/*
+ * QEMU S390x CPU Topology
+ *
+ * Copyright IBM Corp. 2022
+ * Author(s): Pierre Morel 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/s390x/pv.h"
+#include "hw/sysbus.h"
+#include "hw/s390x/cpu-topology.h"
+#include "hw/s390x/sclp.h"
+
+#define S390_TOPOLOGY_MAX_STSI_SIZE (S390_MAX_CPUS *  \
+ (sizeof(SysIB_151x) +\
+