* [PATCH v2 0/4] linux-user: Emulate /proc/cpuinfo on s390x
@ 2023-06-05 11:39 Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 1/4] s390x/tcg: Fix CPU address returned by STIDP Ilya Leoshkevich
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Ilya Leoshkevich @ 2023-06-05 11:39 UTC (permalink / raw)
To: Laurent Vivier, David Hildenbrand, Thomas Huth, Richard Henderson
Cc: qemu-devel, qemu-s390x, Ilya Leoshkevich
v1: https://lists.gnu.org/archive/html/qemu-devel/2023-06/msg00299.html
v1 -> v2: Add output examples (David).
Simplify the CPU 0 special case (David).
Fix building on s390x hosts.
Hi,
This series introduces /proc/cpuinfo linux-user emulation for s390x.
/proc/cpuinfo emulation already exists for sparc, hppa and riscv; this
series follows the pattern established for these platforms.
Patch 1 is a fix for an issue that I noticed while looking for ways to
get to the "identification" field.
Patches 2 and 3 introduce the necessary helpers.
Patch 4 is the actual implementation.
The trigger for this work is a bug report filed by Tulio [1], which has
to do with the llvm-project testcases failing under qemu-user.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=2211472
Best regards,
Ilya
Ilya Leoshkevich (4):
s390x/tcg: Fix CPU address returned by STIDP
linux-user/elfload: Expose get_elf_hwcap() on s390x
linux-user/elfload: Introduce elf_hwcap_str() on s390x
linux-user: Emulate /proc/cpuinfo on s390x
linux-user/elfload.c | 29 ++++++++++-
linux-user/loader.h | 5 ++
linux-user/syscall.c | 106 +++++++++++++++++++++++++++++++++++++-
target/s390x/cpu_models.c | 4 +-
target/s390x/cpu_models.h | 10 +++-
5 files changed, 148 insertions(+), 6 deletions(-)
--
2.40.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/4] s390x/tcg: Fix CPU address returned by STIDP
2023-06-05 11:39 [PATCH v2 0/4] linux-user: Emulate /proc/cpuinfo on s390x Ilya Leoshkevich
@ 2023-06-05 11:39 ` Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 2/4] linux-user/elfload: Expose get_elf_hwcap() on s390x Ilya Leoshkevich
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Ilya Leoshkevich @ 2023-06-05 11:39 UTC (permalink / raw)
To: Laurent Vivier, David Hildenbrand, Thomas Huth, Richard Henderson
Cc: qemu-devel, qemu-s390x, Ilya Leoshkevich
In qemu-user-s390x, /proc/cpuinfo contains:
processor 0: version = 00, identification = 000000, machine = 8561
processor 1: version = 00, identification = 400000, machine = 8561
The highest nibble is supposed to contain the CPU address, but it's off
by 2 bits. Fix the shift value and provide a symbolic constant for it.
With the fix we get:
processor 0: version = 00, identification = 000000, machine = 8561
processor 1: version = 00, identification = 100000, machine = 8561
Fixes: 076d4d39b65f ("s390x/cpumodel: wire up cpu type + id for TCG")
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
target/s390x/cpu_models.c | 4 ++--
target/s390x/cpu_models.h | 10 +++++++++-
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 457b5cb10c4..ae8880e81dc 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -607,8 +607,8 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
#if !defined(CONFIG_USER_ONLY)
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.core_id);
+ cpu->env.cpuid = deposit64(cpu->env.cpuid, CPU_PHYS_ADDR_SHIFT,
+ CPU_PHYS_ADDR_BITS, cpu->env.core_id);
}
#endif
}
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
index fb1adc8b210..cc7305ec213 100644
--- a/target/s390x/cpu_models.h
+++ b/target/s390x/cpu_models.h
@@ -96,10 +96,18 @@ static inline bool s390_known_cpu_type(uint16_t type)
{
return s390_get_gen_for_cpu_type(type) != 0;
}
+#define CPU_ID_SHIFT 32
+#define CPU_ID_BITS 24
+/*
+ * When cpu_id_format is 0 (basic mode), the leftmost 4 bits of cpu_id contain
+ * the rightmost 4 bits of the physical CPU address.
+ */
+#define CPU_PHYS_ADDR_BITS 4
+#define CPU_PHYS_ADDR_SHIFT (CPU_ID_SHIFT + CPU_ID_BITS - CPU_PHYS_ADDR_BITS)
static inline uint64_t s390_cpuid_from_cpu_model(const S390CPUModel *model)
{
return ((uint64_t)model->cpu_ver << 56) |
- ((uint64_t)model->cpu_id << 32) |
+ ((uint64_t)model->cpu_id << CPU_ID_SHIFT) |
((uint64_t)model->def->type << 16) |
(model->def->gen == 7 ? 0 : (uint64_t)model->cpu_id_format << 15);
}
--
2.40.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/4] linux-user/elfload: Expose get_elf_hwcap() on s390x
2023-06-05 11:39 [PATCH v2 0/4] linux-user: Emulate /proc/cpuinfo on s390x Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 1/4] s390x/tcg: Fix CPU address returned by STIDP Ilya Leoshkevich
@ 2023-06-05 11:39 ` Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 3/4] linux-user/elfload: Introduce elf_hwcap_str() " Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 4/4] linux-user: Emulate /proc/cpuinfo " Ilya Leoshkevich
3 siblings, 0 replies; 5+ messages in thread
From: Ilya Leoshkevich @ 2023-06-05 11:39 UTC (permalink / raw)
To: Laurent Vivier, David Hildenbrand, Thomas Huth, Richard Henderson
Cc: qemu-devel, qemu-s390x, Ilya Leoshkevich
It is required for implementing /proc/cpuinfo emulation.
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
linux-user/elfload.c | 2 +-
linux-user/loader.h | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 418ad92598c..49ec9ccc944 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1583,7 +1583,7 @@ static inline void init_thread(struct target_pt_regs *regs,
#define GET_FEATURE(_feat, _hwcap) \
do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0)
-static uint32_t get_elf_hwcap(void)
+uint32_t get_elf_hwcap(void)
{
/*
* Let's assume we always have esan3 and zarch.
diff --git a/linux-user/loader.h b/linux-user/loader.h
index f375ee0679b..ad6ca9dbe35 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -56,4 +56,8 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
extern unsigned long guest_stack_size;
+#ifdef TARGET_S390X
+uint32_t get_elf_hwcap(void);
+#endif
+
#endif /* LINUX_USER_LOADER_H */
--
2.40.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 3/4] linux-user/elfload: Introduce elf_hwcap_str() on s390x
2023-06-05 11:39 [PATCH v2 0/4] linux-user: Emulate /proc/cpuinfo on s390x Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 1/4] s390x/tcg: Fix CPU address returned by STIDP Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 2/4] linux-user/elfload: Expose get_elf_hwcap() on s390x Ilya Leoshkevich
@ 2023-06-05 11:39 ` Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 4/4] linux-user: Emulate /proc/cpuinfo " Ilya Leoshkevich
3 siblings, 0 replies; 5+ messages in thread
From: Ilya Leoshkevich @ 2023-06-05 11:39 UTC (permalink / raw)
To: Laurent Vivier, David Hildenbrand, Thomas Huth, Richard Henderson
Cc: qemu-devel, qemu-s390x, Ilya Leoshkevich
It is required for implementing /proc/cpuinfo emulation.
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
linux-user/elfload.c | 27 +++++++++++++++++++++++++++
linux-user/loader.h | 1 +
2 files changed, 28 insertions(+)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 49ec9ccc944..d80d68484b6 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1605,6 +1605,33 @@ uint32_t get_elf_hwcap(void)
return hwcap;
}
+const char *elf_hwcap_str(uint32_t bit)
+{
+ static const char *hwcap_str[] = {
+ [HWCAP_S390_ESAN3] = "esan3",
+ [HWCAP_S390_ZARCH] = "zarch",
+ [HWCAP_S390_STFLE] = "stfle",
+ [HWCAP_S390_MSA] = "msa",
+ [HWCAP_S390_LDISP] = "ldisp",
+ [HWCAP_S390_EIMM] = "eimm",
+ [HWCAP_S390_DFP] = "dfp",
+ [HWCAP_S390_HPAGE] = "edat",
+ [HWCAP_S390_ETF3EH] = "etf3eh",
+ [HWCAP_S390_HIGH_GPRS] = "highgprs",
+ [HWCAP_S390_TE] = "te",
+ [HWCAP_S390_VXRS] = "vx",
+ [HWCAP_S390_VXRS_BCD] = "vxd",
+ [HWCAP_S390_VXRS_EXT] = "vxe",
+ [HWCAP_S390_GS] = "gs",
+ [HWCAP_S390_VXRS_EXT2] = "vxe2",
+ [HWCAP_S390_VXRS_PDE] = "vxp",
+ [HWCAP_S390_SORT] = "sort",
+ [HWCAP_S390_DFLT] = "dflt",
+ };
+
+ return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
+}
+
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
regs->psw.addr = infop->entry;
diff --git a/linux-user/loader.h b/linux-user/loader.h
index ad6ca9dbe35..59cbeacf24f 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -58,6 +58,7 @@ extern unsigned long guest_stack_size;
#ifdef TARGET_S390X
uint32_t get_elf_hwcap(void);
+const char *elf_hwcap_str(uint32_t bit);
#endif
#endif /* LINUX_USER_LOADER_H */
--
2.40.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 4/4] linux-user: Emulate /proc/cpuinfo on s390x
2023-06-05 11:39 [PATCH v2 0/4] linux-user: Emulate /proc/cpuinfo on s390x Ilya Leoshkevich
` (2 preceding siblings ...)
2023-06-05 11:39 ` [PATCH v2 3/4] linux-user/elfload: Introduce elf_hwcap_str() " Ilya Leoshkevich
@ 2023-06-05 11:39 ` Ilya Leoshkevich
3 siblings, 0 replies; 5+ messages in thread
From: Ilya Leoshkevich @ 2023-06-05 11:39 UTC (permalink / raw)
To: Laurent Vivier, David Hildenbrand, Thomas Huth, Richard Henderson
Cc: qemu-devel, qemu-s390x, Ilya Leoshkevich,
Tulio Magno Quites Machado Filho
Some s390x userspace programs are confused when seeing a foreign
/proc/cpuinfo [1]. Add the emulation for s390x; follow the respective
kernel code structure where possible.
Output example:
vendor_id : IBM/S390
# processors : 12
bogomips per cpu: 13370.00
max thread id : 0
features : esan3 zarch stfle msa
facilities : 0 1 2 3 4 7 9 16 17 18 19 21 22 24 25 27 30 31 32 33 34 35 37 40 41 45 49 51 52 53 57 58 61 69 71 72 75 76 77 129 130 131 135 138 146 148
processor 0: version = 00, identification = 000000, machine = 8561
processor 1: version = 00, identification = 100000, machine = 8561
[...]
cpu number : 0
version : 00
identification : 000000
machine : 8561
cpu number : 1
version : 00
identification : 100000
machine : 8561
[...]
[1] https://bugzilla.redhat.com/show_bug.cgi?id=2211472
Reported-by: Tulio Magno Quites Machado Filho <tuliom@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
linux-user/syscall.c | 106 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 104 insertions(+), 2 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3e6ed51ce62..2d3070cfd62 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8232,7 +8232,7 @@ void target_exception_dump(CPUArchState *env, const char *fmt, int code)
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \
defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) || \
- defined(TARGET_RISCV)
+ defined(TARGET_RISCV) || defined(TARGET_S390X)
static int is_proc(const char *filename, const char *entry)
{
return strcmp(filename, entry) == 0;
@@ -8339,6 +8339,107 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
}
#endif
+#if defined(TARGET_S390X)
+/*
+ * Emulate what a Linux kernel running in qemu-system-s390x -M accel=tcg would
+ * show in /proc/cpuinfo.
+ *
+ * Skip the following in order to match the missing support in op_ecag():
+ * - show_cacheinfo().
+ * - show_cpu_topology().
+ * - show_cpu_mhz().
+ *
+ * Use fixed values for certain fields:
+ * - bogomips per cpu - from a qemu-system-s390x run.
+ * - max thread id = 0, since SMT / SIGP_SET_MULTI_THREADING is not supported.
+ *
+ * Keep the code structure close to arch/s390/kernel/processor.c.
+ */
+
+static void show_facilities(int fd)
+{
+ size_t sizeof_stfl_bytes = 2048;
+ g_autofree uint8_t *stfl_bytes = g_new0(uint8_t, sizeof_stfl_bytes);
+ unsigned int bit;
+
+ dprintf(fd, "facilities :");
+ s390_get_feat_block(S390_FEAT_TYPE_STFL, stfl_bytes);
+ for (bit = 0; bit < sizeof_stfl_bytes * 8; bit++) {
+ if (test_be_bit(bit, stfl_bytes)) {
+ dprintf(fd, " %d", bit);
+ }
+ }
+ dprintf(fd, "\n");
+}
+
+static int cpu_ident(unsigned long n)
+{
+ return deposit32(0, CPU_ID_BITS - CPU_PHYS_ADDR_BITS, CPU_PHYS_ADDR_BITS,
+ n);
+}
+
+static void show_cpu_summary(CPUArchState *cpu_env, int fd)
+{
+ S390CPUModel *model = env_archcpu(cpu_env)->model;
+ int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ uint32_t elf_hwcap = get_elf_hwcap();
+ const char *hwcap_str;
+ int i;
+
+ dprintf(fd, "vendor_id : IBM/S390\n"
+ "# processors : %i\n"
+ "bogomips per cpu: 13370.00\n",
+ num_cpus);
+ dprintf(fd, "max thread id : 0\n");
+ dprintf(fd, "features\t: ");
+ for (i = 0; i < sizeof(elf_hwcap) * 8; i++) {
+ if (!(elf_hwcap & (1 << i))) {
+ continue;
+ }
+ hwcap_str = elf_hwcap_str(i);
+ if (hwcap_str) {
+ dprintf(fd, "%s ", hwcap_str);
+ }
+ }
+ dprintf(fd, "\n");
+ show_facilities(fd);
+ for (i = 0; i < num_cpus; i++) {
+ dprintf(fd, "processor %d: "
+ "version = %02X, "
+ "identification = %06X, "
+ "machine = %04X\n",
+ i, model->cpu_ver, cpu_ident(i), model->def->type);
+ }
+}
+
+static void show_cpu_ids(CPUArchState *cpu_env, int fd, unsigned long n)
+{
+ S390CPUModel *model = env_archcpu(cpu_env)->model;
+
+ dprintf(fd, "version : %02X\n", model->cpu_ver);
+ dprintf(fd, "identification : %06X\n", cpu_ident(n));
+ dprintf(fd, "machine : %04X\n", model->def->type);
+}
+
+static void show_cpuinfo(CPUArchState *cpu_env, int fd, unsigned long n)
+{
+ dprintf(fd, "\ncpu number : %ld\n", n);
+ show_cpu_ids(cpu_env, fd, n);
+}
+
+static int open_cpuinfo(CPUArchState *cpu_env, int fd)
+{
+ int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ int i;
+
+ show_cpu_summary(cpu_env, fd);
+ for (i = 0; i < num_cpus; i++) {
+ show_cpuinfo(cpu_env, fd, i);
+ }
+ return 0;
+}
+#endif
+
#if defined(TARGET_M68K)
static int open_hardware(CPUArchState *cpu_env, int fd)
{
@@ -8364,7 +8465,8 @@ int do_guest_openat(CPUArchState *cpu_env, int dirfd, const char *pathname,
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
{ "/proc/net/route", open_net_route, is_proc },
#endif
-#if defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined(TARGET_RISCV)
+#if defined(TARGET_SPARC) || defined(TARGET_HPPA) || \
+ defined(TARGET_RISCV) || defined(TARGET_S390X)
{ "/proc/cpuinfo", open_cpuinfo, is_proc },
#endif
#if defined(TARGET_M68K)
--
2.40.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-06-05 11:41 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-05 11:39 [PATCH v2 0/4] linux-user: Emulate /proc/cpuinfo on s390x Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 1/4] s390x/tcg: Fix CPU address returned by STIDP Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 2/4] linux-user/elfload: Expose get_elf_hwcap() on s390x Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 3/4] linux-user/elfload: Introduce elf_hwcap_str() " Ilya Leoshkevich
2023-06-05 11:39 ` [PATCH v2 4/4] linux-user: Emulate /proc/cpuinfo " Ilya Leoshkevich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).