* [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework
@ 2026-08-24 14:35 Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 01/13] lib: s390x: Add function to get page root Janosch Frank
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini; +Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth
We've finally accumulated enough patches for a pull/merge request:
STFLE interpretation facility tests (Christoph & Nina)
stsi 3.2.2 regression test (Christian)
sie lib rework & fixes around test execution
Please pull/merge.
Thanks,
Janosch
Pull:
https://gitlab.com/frankja/kvm-unit-tests.git s390x-pull-2026-08
Merge:
https://gitlab.com/kvm-unit-tests/kvm-unit-tests/-/merge_requests/88
Christian Borntraeger (1):
s390x: stsi: regression test for the STSI 3.2.2 count clamp
Christoph Schlameuss (4):
s390x: sclp: Remove unnecessary padding from struct sclp_facilities
s390x: sclp: Check sclp byte before reading feature bits
s390x: sclp: Use sclp_feat_check directly to read DIAG318 feature bit
s390x: Add test for STFLE interpretive execution (format-2)
Janosch Frank (6):
lib: s390x: Add function to get page root
lib: s390x: sie: Allocate physical guest memory via memalign
lib: s390x: sie: Memory rework
lib: s390x: snippet: Add function to create a guest of specific length
s390x: unittests: Reenable tcg for migration tests
s390x: skey: Fence TCG protection checks
Nina Schoetterl-Glausch (2):
s390x: snippets: Add reset_guest() to lib
s390x: sclp: Add detection of alternate STFLE facilities
lib/s390x/mmu.h | 7 +++++
lib/s390x/sclp.c | 8 +++--
lib/s390x/sclp.h | 8 +++--
lib/s390x/sie.c | 22 +++++++++++--
lib/s390x/sie.h | 3 +-
lib/s390x/snippet.h | 25 ++++++++++++---
s390x/diag258.c | 4 +--
s390x/edat.c | 5 +--
s390x/mvpg-sie.c | 4 +--
s390x/pv-diags.c | 2 +-
s390x/pv-icptcode.c | 4 +--
s390x/pv-ipl.c | 2 +-
s390x/sie-dat.c | 4 +--
s390x/sie.c | 13 +++-----
s390x/skey.c | 15 ++++++---
s390x/spec_ex-sie.c | 12 +++----
s390x/stfle-sie.c | 74 ++++++++++++++++++++++++++++++++++++++++---
s390x/stsi.c | 76 ++++++++++++++++++++++++++++++++++++++++++++-
s390x/unittests.cfg | 7 +----
19 files changed, 237 insertions(+), 58 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 01/13] lib: s390x: Add function to get page root
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 02/13] lib: s390x: sie: Allocate physical guest memory via memalign Janosch Frank
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Christoph Schlameuss, Nico Boehr
It's time to hide the access to cr1 behind a function and add typing
to the tests that used void* instead of pgdt_t*.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Reviewed-by: Nico Boehr <nrb@linux.ibm.com>
---
lib/s390x/mmu.h | 7 +++++++
lib/s390x/sie.c | 3 ++-
s390x/diag258.c | 4 ++--
s390x/edat.c | 5 +++--
s390x/mvpg-sie.c | 2 +-
s390x/sie-dat.c | 2 +-
s390x/skey.c | 7 +++----
7 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/lib/s390x/mmu.h b/lib/s390x/mmu.h
index dadc2e60..19c46c58 100644
--- a/lib/s390x/mmu.h
+++ b/lib/s390x/mmu.h
@@ -10,6 +10,8 @@
#ifndef _S390X_MMU_H_
#define _S390X_MMU_H_
+#include <asm/arch_def.h>
+
enum pgt_level {
pgtable_level_pgd = 1,
pgtable_level_p4d,
@@ -95,4 +97,9 @@ static inline void unprotect_page(void *vaddr, unsigned long prot)
void *get_dat_entry(pgd_t *pgtable, void *vaddr, enum pgt_level level);
+static inline pgd_t *get_primary_page_root(void)
+{
+ return (pgd_t *)(stctg(1) & PAGE_MASK);
+}
+
#endif /* _ASMS390X_MMU_H_ */
diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c
index 0fa915cf..47d4cdde 100644
--- a/lib/s390x/sie.c
+++ b/lib/s390x/sie.c
@@ -17,6 +17,7 @@
#include <alloc_page.h>
#include <vmalloc.h>
#include <sclp.h>
+#include <mmu.h>
void sie_expect_validity(struct vm *vm)
{
@@ -156,7 +157,7 @@ uint8_t *sie_guest_alloc(uint64_t guest_size)
pgd_t *root;
setup_vm();
- root = (pgd_t *)(stctg(1) & PAGE_MASK);
+ root = get_primary_page_root();
/*
* Start of guest memory in host virtual space needs to be aligned to
diff --git a/s390x/diag258.c b/s390x/diag258.c
index 8ba75a72..2482ecf3 100644
--- a/s390x/diag258.c
+++ b/s390x/diag258.c
@@ -82,7 +82,7 @@ static void test_priv(void)
static void *page_map_outside_real_space(phys_addr_t page_real)
{
- pgd_t *root = (pgd_t *)(stctg(1) & PAGE_MASK);
+ pgd_t *root = get_primary_page_root();
void *vaddr = alloc_vpage();
install_page(root, page_real, vaddr);
@@ -109,7 +109,7 @@ static void test_refbk_real(void)
refbk_page = alloc_page();
/* Map refblk page outside of physical memory identity mapping */
- root = (pgd_t *)(stctg(1) & PAGE_MASK);
+ root = get_primary_page_root();
refbk = page_map_outside_real_space(virt_to_pte_phys(root, refbk_page));
/* Assert the mapping really is outside identity mapping */
diff --git a/s390x/edat.c b/s390x/edat.c
index 89b9c2d3..e54cd642 100644
--- a/s390x/edat.c
+++ b/s390x/edat.c
@@ -21,7 +21,8 @@
static uint8_t prefix_buf[LC_SIZE] __attribute__((aligned(LC_SIZE)));
static unsigned int tmp[1024] __attribute__((aligned(PAGE_SIZE)));
-static void *root, *mem, *m;
+static void *mem, *m;
+static pgd_t *root;
volatile unsigned int *p;
/*
@@ -237,7 +238,7 @@ static unsigned int setup(void)
/* Setup DAT 1:1 mapping and memory management */
setup_vm();
- root = (void *)(stctg(1) & PAGE_MASK);
+ root = get_primary_page_root();
/*
* Get a pgd worth of virtual memory, so we can test things later
diff --git a/s390x/mvpg-sie.c b/s390x/mvpg-sie.c
index d182b49a..920dee29 100644
--- a/s390x/mvpg-sie.c
+++ b/s390x/mvpg-sie.c
@@ -88,7 +88,7 @@ static void setup_guest(void)
pgd_t *root;
setup_vm();
- root = (pgd_t *)(stctg(1) & PAGE_MASK);
+ root = get_primary_page_root();
snippet_setup_guest(&vm, false);
snippet_init(&vm, SNIPPET_NAME_START(c, mvpg_snippet),
diff --git a/s390x/sie-dat.c b/s390x/sie-dat.c
index 44bf29fe..e40e348f 100644
--- a/s390x/sie-dat.c
+++ b/s390x/sie-dat.c
@@ -69,7 +69,7 @@ static void setup_guest(void)
pgd_t *root;
setup_vm();
- root = (pgd_t *)(stctg(1) & PAGE_MASK);
+ root = get_primary_page_root();
snippet_setup_guest(&vm, false);
diff --git a/s390x/skey.c b/s390x/skey.c
index 7c7a8090..bb769730 100644
--- a/s390x/skey.c
+++ b/s390x/skey.c
@@ -13,6 +13,7 @@
#include <asm/interrupt.h>
#include <vmalloc.h>
#include <css.h>
+#include <mmu.h>
#include <asm/page.h>
#include <asm/facility.h>
#include <asm/mem.h>
@@ -465,10 +466,9 @@ static void test_set_prefix(void)
uint32_t *prefix_ptr = (uint32_t *)pagebuf;
uint32_t *no_override_prefix_ptr;
uint32_t old_prefix;
- pgd_t *root;
+ pgd_t *root = get_primary_page_root();
report_prefix_push("SET PREFIX");
- root = (pgd_t *)(stctg(1) & PAGE_MASK);
old_prefix = get_prefix();
memcpy(lowcore_tmp, 0, sizeof(lowcore_tmp));
assert(((uint64_t)&lowcore_tmp >> 31) == 0);
@@ -583,11 +583,10 @@ static void test_msch(void)
struct schib *schib = (struct schib *)pagebuf;
struct schib *no_override_schib;
int test_device_sid;
- pgd_t *root;
+ pgd_t *root = get_primary_page_root();
int cc;
report_prefix_push("MSCH");
- root = (pgd_t *)(stctg(1) & PAGE_MASK);
test_device_sid = css_enumerate();
if (!(test_device_sid & SCHID_ONE)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 02/13] lib: s390x: sie: Allocate physical guest memory via memalign
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 01/13] lib: s390x: Add function to get page root Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 03/13] lib: s390x: sie: Memory rework Janosch Frank
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Christoph Schlameuss, Nico Boehr
alloc_pages_flags() alignes the allocation on the same order as its
requested size. Since we use virtual memory for SIE we can instead
align to 1MB by using memalign() which is less wasteful.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Reviewed-by: Nico Boehr <nrb@linux.ibm.com>
---
lib/s390x/sie.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c
index 47d4cdde..8757f610 100644
--- a/lib/s390x/sie.c
+++ b/lib/s390x/sie.c
@@ -171,7 +171,8 @@ uint8_t *sie_guest_alloc(uint64_t guest_size)
guest_virt = (uint8_t *)ALIGN(get_ram_size() + guest_counter * 4UL * SZ_1G, SZ_2G);
guest_counter++;
- guest_phys = alloc_pages(get_order(guest_size) - 12);
+ guest_phys = memalign_pages(SZ_1M, guest_size);
+ assert(guest_phys);
/*
* Establish a new mapping of the guest memory so it can be 2GB aligned
* without actually requiring 2GB physical memory.
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 03/13] lib: s390x: sie: Memory rework
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 01/13] lib: s390x: Add function to get page root Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 02/13] lib: s390x: sie: Allocate physical guest memory via memalign Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 04/13] lib: s390x: snippet: Add function to create a guest of specific length Janosch Frank
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Christoph Schlameuss
Make sie_guest_create() directly alloc the guest's memory.
Also we never freed the memory that the sie library allocates as the guest
ram on destruction of the VM. Most tests reuse the VM or just leak the
memory since the standard allocation is one megabyte and tests only
use single digit numbers of VMs.
It's time to add automatic freeing to the sie library when a VM is
destroyed.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
---
lib/s390x/sie.c | 5 ++++-
lib/s390x/sie.h | 2 +-
lib/s390x/snippet.h | 9 +++++----
s390x/mvpg-sie.c | 2 +-
s390x/pv-diags.c | 2 +-
s390x/pv-icptcode.c | 4 ++--
s390x/pv-ipl.c | 2 +-
s390x/sie-dat.c | 2 +-
s390x/sie.c | 13 ++++---------
s390x/spec_ex-sie.c | 2 ++
s390x/stfle-sie.c | 2 ++
11 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c
index 8757f610..ad1f2ade 100644
--- a/lib/s390x/sie.c
+++ b/lib/s390x/sie.c
@@ -122,8 +122,10 @@ void sie_guest_sca_create(struct vm *vm)
}
/* Initializes the struct vm members like the SIE control block. */
-void sie_guest_create(struct vm *vm, uint64_t guest_mem, uint64_t guest_mem_len)
+void sie_guest_create(struct vm *vm, uint64_t guest_mem_len)
{
+ void *guest_mem = sie_guest_alloc(guest_mem_len);
+
vm->sblk = alloc_page();
memset(vm->sblk, 0, PAGE_SIZE);
vm->sblk->cpuflags = CPUSTAT_ZARCH | CPUSTAT_RUNNING;
@@ -192,4 +194,5 @@ void sie_guest_destroy(struct vm *vm)
free_page(vm->sblk);
if (vm->sblk->ecb2 & ECB2_ESCA)
free_page(vm->sca);
+ free_pages((void *)virt_to_pte_phys(get_primary_page_root(), vm->guest_mem));
}
diff --git a/lib/s390x/sie.h b/lib/s390x/sie.h
index 3ec49ed0..85d691d5 100644
--- a/lib/s390x/sie.h
+++ b/lib/s390x/sie.h
@@ -59,7 +59,7 @@ static inline bool sie_is_pv(struct vm *vm)
}
void sie_guest_sca_create(struct vm *vm);
-void sie_guest_create(struct vm *vm, uint64_t guest_mem, uint64_t guest_mem_len);
+void sie_guest_create(struct vm *vm, uint64_t guest_mem_len);
void sie_guest_destroy(struct vm *vm);
uint8_t *sie_guest_alloc(uint64_t guest_size);
diff --git a/lib/s390x/snippet.h b/lib/s390x/snippet.h
index 910849aa..94688f49 100644
--- a/lib/s390x/snippet.h
+++ b/lib/s390x/snippet.h
@@ -125,11 +125,8 @@ static inline void snippet_pv_init(struct vm *vm, const char *gbin,
/* Allocates and sets up a snippet based guest */
static inline void snippet_setup_guest(struct vm *vm, bool is_pv)
{
- const unsigned long guest_size = SZ_1M;
- uint8_t *guest_start = sie_guest_alloc(guest_size);
-
/* Initialize the vm struct and allocate control blocks */
- sie_guest_create(vm, (uint64_t)guest_start, guest_size);
+ sie_guest_create(vm, SZ_1M);
if (is_pv) {
/* FMT4 needs a ESCA */
@@ -144,4 +141,8 @@ static inline void snippet_setup_guest(struct vm *vm, bool is_pv)
}
}
+static inline void snippet_destroy_guest(struct vm *vm)
+{
+ sie_guest_destroy(vm);
+}
#endif
diff --git a/s390x/mvpg-sie.c b/s390x/mvpg-sie.c
index 920dee29..ac33923c 100644
--- a/s390x/mvpg-sie.c
+++ b/s390x/mvpg-sie.c
@@ -117,7 +117,7 @@ int main(void)
setup_guest();
test_mvpg();
test_mvpg_pei();
- sie_guest_destroy(&vm);
+ snippet_destroy_guest(&vm);
done:
report_prefix_pop();
diff --git a/s390x/pv-diags.c b/s390x/pv-diags.c
index 09b83d59..b6f08dd2 100644
--- a/s390x/pv-diags.c
+++ b/s390x/pv-diags.c
@@ -156,7 +156,7 @@ int main(void)
test_diag_yield();
test_diag_288();
test_diag_500();
- sie_guest_destroy(&vm);
+ snippet_destroy_guest(&vm);
done:
report_prefix_pop();
diff --git a/s390x/pv-icptcode.c b/s390x/pv-icptcode.c
index 5293306b..bdef3a05 100644
--- a/s390x/pv-icptcode.c
+++ b/s390x/pv-icptcode.c
@@ -164,7 +164,7 @@ static void test_validity_handle_not_in_config(void)
/* Destroy the second vm, since we don't need it for further tests */
uv_destroy_guest(&vm2);
- sie_guest_destroy(&vm2);
+ snippet_destroy_guest(&vm2);
uv_destroy_guest(&vm);
report_prefix_pop();
@@ -368,7 +368,7 @@ int main(void)
test_validity_handle_not_in_config();
test_validity_already_running();
test_validity_timing();
- sie_guest_destroy(&vm);
+ snippet_destroy_guest(&vm);
done:
report_prefix_pop();
diff --git a/s390x/pv-ipl.c b/s390x/pv-ipl.c
index 61a1e0c0..1219573f 100644
--- a/s390x/pv-ipl.c
+++ b/s390x/pv-ipl.c
@@ -135,7 +135,7 @@ int main(void)
snippet_setup_guest(&vm, true);
test_diag_308(0);
test_diag_308(1);
- sie_guest_destroy(&vm);
+ snippet_destroy_guest(&vm);
done:
report_prefix_pop();
diff --git a/s390x/sie-dat.c b/s390x/sie-dat.c
index e40e348f..a5ff0872 100644
--- a/s390x/sie-dat.c
+++ b/s390x/sie-dat.c
@@ -101,7 +101,7 @@ int main(void)
setup_guest();
test_sie_dat();
- sie_guest_destroy(&vm);
+ snippet_destroy_guest(&vm);
done:
report_prefix_pop();
diff --git a/s390x/sie.c b/s390x/sie.c
index ce5b6069..f08564b1 100644
--- a/s390x/sie.c
+++ b/s390x/sie.c
@@ -20,7 +20,6 @@
#include <sclp.h>
#include <sie.h>
-static u8 *guest;
static u8 *guest_instr;
static struct vm vm;
@@ -70,7 +69,7 @@ static void test_epoch_ext(void)
return;
}
- guest[0] = 0x00;
+ vm.guest_mem[0] = 0x00;
memcpy(guest_instr, instr, sizeof(instr));
vm.sblk->gpsw.addr = PAGE_SIZE * 2;
@@ -82,19 +81,15 @@ static void test_epoch_ext(void)
sie(&vm);
/* ... should result in the same epoch extension here: */
- report(guest[0] == 0x47, "epdx: different epoch is visible in the guest");
+ report(vm.guest_mem[0] == 0x47, "epdx: different epoch is visible in the guest");
}
static void setup_guest(void)
{
- setup_vm();
-
- guest = sie_guest_alloc(SZ_1M);
+ sie_guest_create(&vm, HPAGE_SIZE);
/* The first two pages are the lowcore */
- guest_instr = guest + PAGE_SIZE * 2;
-
- sie_guest_create(&vm, (uint64_t)guest, HPAGE_SIZE);
+ guest_instr = vm.guest_mem + PAGE_SIZE * 2;
}
int main(void)
diff --git a/s390x/spec_ex-sie.c b/s390x/spec_ex-sie.c
index fe2f23ee..6ab4144c 100644
--- a/s390x/spec_ex-sie.c
+++ b/s390x/spec_ex-sie.c
@@ -71,6 +71,8 @@ static void test_spec_ex_sie(void)
report_info("%s", msg);
else
report_info("Did not interpret initial exception");
+
+ snippet_destroy_guest(&vm);
report_prefix_pop();
report_prefix_pop();
}
diff --git a/s390x/stfle-sie.c b/s390x/stfle-sie.c
index 21cf8ff8..8df1185c 100644
--- a/s390x/stfle-sie.c
+++ b/s390x/stfle-sie.c
@@ -133,6 +133,8 @@ int main(int argc, char **argv)
setup_guest();
if (run_format_0)
test_stfle_format_0();
+
+ snippet_destroy_guest(&vm);
out:
return report_summary();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 04/13] lib: s390x: snippet: Add function to create a guest of specific length
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (2 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 03/13] lib: s390x: sie: Memory rework Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 05/13] s390x: snippets: Add reset_guest() to lib Janosch Frank
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Nico Boehr, Christoph Schlameuss
While 1MB is certainly enough to store the guest code, it's often not
enough for memory tests. Let's add a separate function to allow
arbitrary guest sizes.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Nico Boehr <nrb@linux.ibm.com>
Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
---
lib/s390x/snippet.h | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/s390x/snippet.h b/lib/s390x/snippet.h
index 94688f49..05c9a2d4 100644
--- a/lib/s390x/snippet.h
+++ b/lib/s390x/snippet.h
@@ -123,10 +123,14 @@ static inline void snippet_pv_init(struct vm *vm, const char *gbin,
}
/* Allocates and sets up a snippet based guest */
-static inline void snippet_setup_guest(struct vm *vm, bool is_pv)
+static inline void snippet_setup_guest_len(struct vm *vm, bool is_pv,
+ unsigned long len)
{
+ /* Guest sizes are specified in megabyte chunks */
+ assert(!(len & ~HPAGE_MASK));
+
/* Initialize the vm struct and allocate control blocks */
- sie_guest_create(vm, SZ_1M);
+ sie_guest_create(vm, len);
if (is_pv) {
/* FMT4 needs a ESCA */
@@ -141,6 +145,12 @@ static inline void snippet_setup_guest(struct vm *vm, bool is_pv)
}
}
+/* Allocates and sets up a snippet based guest */
+static inline void snippet_setup_guest(struct vm *vm, bool is_pv)
+{
+ snippet_setup_guest_len(vm, is_pv, SZ_1M);
+}
+
static inline void snippet_destroy_guest(struct vm *vm)
{
sie_guest_destroy(vm);
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 05/13] s390x: snippets: Add reset_guest() to lib
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (3 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 04/13] lib: s390x: snippet: Add function to create a guest of specific length Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 06/13] s390x: sclp: Remove unnecessary padding from struct sclp_facilities Janosch Frank
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Nina Schoetterl-Glausch, Christoph Schlameuss, Nico Boehr
From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Extract reset_guest from spec_ex-sie into the lib.
After reset_guest() the snippet can be executed again.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Nico Boehr <nrb@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
lib/s390x/snippet.h | 6 ++++++
s390x/spec_ex-sie.c | 10 ++--------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/lib/s390x/snippet.h b/lib/s390x/snippet.h
index 05c9a2d4..83d74387 100644
--- a/lib/s390x/snippet.h
+++ b/lib/s390x/snippet.h
@@ -83,6 +83,12 @@ static inline void snippet_init(struct vm *vm, const char *gbin,
vm->sblk->ictl = ICTL_OPEREXC | ICTL_PINT;
}
+static inline void reset_guest(struct vm *vm)
+{
+ vm->sblk->gpsw = snippet_psw;
+ vm->sblk->icptcode = 0;
+}
+
/*
* Sets up a snippet UV/PV guest on top of an existing and initialized
* SIE vm struct.
diff --git a/s390x/spec_ex-sie.c b/s390x/spec_ex-sie.c
index 6ab4144c..dd4ab77e 100644
--- a/s390x/spec_ex-sie.c
+++ b/s390x/spec_ex-sie.c
@@ -31,12 +31,6 @@ static void setup_guest(void)
SNIPPET_LEN(c, spec_ex), SNIPPET_UNPACK_OFF);
}
-static void reset_guest(void)
-{
- vm.sblk->gpsw = snippet_psw;
- vm.sblk->icptcode = 0;
-}
-
static void test_spec_ex_sie(void)
{
const char *msg;
@@ -45,7 +39,7 @@ static void test_spec_ex_sie(void)
report_prefix_push("SIE spec ex interpretation");
report_prefix_push("off");
- reset_guest();
+ reset_guest(&vm);
sie(&vm);
/* interpretation off -> initial exception must cause interception */
report(vm.sblk->icptcode == ICPT_PROGI
@@ -56,7 +50,7 @@ static void test_spec_ex_sie(void)
report_prefix_push("on");
vm.sblk->ecb |= ECB_SPECI;
- reset_guest();
+ reset_guest(&vm);
sie(&vm);
/* interpretation on -> configuration dependent if initial exception causes
* interception, but invalid new program PSW must
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 06/13] s390x: sclp: Remove unnecessary padding from struct sclp_facilities
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (4 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 05/13] s390x: snippets: Add reset_guest() to lib Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 07/13] s390x: sclp: Check sclp byte before reading feature bits Janosch Frank
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Christoph Schlameuss, Nico Boehr
From: Christoph Schlameuss <schlameuss@linux.ibm.com>
Struct sclp_facilities is only used within the guest to keep the facility
information. Nothing bad should happen when the struct size changes in the
future.
Suggested-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Nico Boehr <nrb@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
lib/s390x/sclp.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/s390x/sclp.h b/lib/s390x/sclp.h
index 22f120d1..42a2f2e9 100644
--- a/lib/s390x/sclp.h
+++ b/lib/s390x/sclp.h
@@ -132,7 +132,6 @@ struct sclp_facilities {
uint64_t has_kss : 1;
uint64_t has_pfmfi : 1;
uint64_t has_ibs : 1;
- uint64_t : 64 - 15;
};
/* bit number within a certain byte */
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 07/13] s390x: sclp: Check sclp byte before reading feature bits
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (5 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 06/13] s390x: sclp: Remove unnecessary padding from struct sclp_facilities Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 08/13] s390x: sclp: Use sclp_feat_check directly to read DIAG318 feature bit Janosch Frank
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Christoph Schlameuss, Nico Boehr
From: Christoph Schlameuss <schlameuss@linux.ibm.com>
Improve the readability and simplicity of the code in
sclp_facilities_setup() by moving the check for availabity of feature bits
into sclp_feat_check().
Suggested-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Nico Boehr <nrb@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
lib/s390x/sclp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/s390x/sclp.c b/lib/s390x/sclp.c
index 2f902e39..1ffcf448 100644
--- a/lib/s390x/sclp.c
+++ b/lib/s390x/sclp.c
@@ -142,6 +142,9 @@ static bool sclp_feat_check(int byte, int bit)
{
uint8_t *rib = (uint8_t *)read_info;
+ if (read_info->offset_cpu <= byte)
+ return false;
+
return !!(rib[byte] & (0x80 >> bit));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 08/13] s390x: sclp: Use sclp_feat_check directly to read DIAG318 feature bit
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (6 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 07/13] s390x: sclp: Check sclp byte before reading feature bits Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 09/13] s390x: sclp: Add detection of alternate STFLE facilities Janosch Frank
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Christoph Schlameuss, Nico Boehr
From: Christoph Schlameuss <schlameuss@linux.ibm.com>
The additional entry in struct ReadInfo is only used to set sclp_facilities
where we are aware where these bits actually are in _read_info. So it is
more readable to directly check the bit here.
While at it order feat checks by byte and bit.
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Nico Boehr <nrb@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
lib/s390x/sclp.c | 3 +--
lib/s390x/sclp.h | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/lib/s390x/sclp.c b/lib/s390x/sclp.c
index 1ffcf448..9d9fd3cb 100644
--- a/lib/s390x/sclp.c
+++ b/lib/s390x/sclp.c
@@ -157,8 +157,6 @@ void sclp_facilities_setup(void)
assert(read_info);
cpu = sclp_get_cpu_entries();
- if (read_info->offset_cpu > 134)
- sclp_facilities.has_diag318 = read_info->byte_134_diag318;
sclp_facilities.has_sop = sclp_feat_check(80, SCLP_FEAT_80_BIT_SOP);
sclp_facilities.has_gsls = sclp_feat_check(85, SCLP_FEAT_85_BIT_GSLS);
sclp_facilities.has_esop = sclp_feat_check(85, SCLP_FEAT_85_BIT_ESOP);
@@ -168,6 +166,7 @@ void sclp_facilities_setup(void)
sclp_facilities.has_esca = sclp_feat_check(116, SCLP_FEAT_116_BIT_ESCA);
sclp_facilities.has_ibs = sclp_feat_check(117, SCLP_FEAT_117_BIT_IBS);
sclp_facilities.has_pfmfi = sclp_feat_check(117, SCLP_FEAT_117_BIT_PFMFI);
+ sclp_facilities.has_diag318 = sclp_feat_check(134, SCLP_FEAT_134_BIT_DIAG318);
for (i = 0; i < read_info->entries_cpu; i++, cpu++) {
/*
diff --git a/lib/s390x/sclp.h b/lib/s390x/sclp.h
index 42a2f2e9..87af429b 100644
--- a/lib/s390x/sclp.h
+++ b/lib/s390x/sclp.h
@@ -144,6 +144,7 @@ struct sclp_facilities {
#define SCLP_FEAT_116_BIT_ESCA 4
#define SCLP_FEAT_117_BIT_PFMFI 1
#define SCLP_FEAT_117_BIT_IBS 2
+#define SCLP_FEAT_134_BIT_DIAG318 0
typedef struct ReadInfo {
SCCBHeader h;
@@ -169,8 +170,6 @@ typedef struct ReadInfo {
uint8_t _reserved5[124 - 122]; /* 122-123 */
uint32_t hmfai;
uint8_t reserved7[134 - 128]; /* 128-133 */
- uint8_t byte_134_diag318 : 1;
- uint8_t : 7;
/*
* At the end of the ReadInfo, there are also the CPU entries (see
* struct CPUEntry). When the Extended-Length SCCB (ELS) feature is
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 09/13] s390x: sclp: Add detection of alternate STFLE facilities
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (7 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 08/13] s390x: sclp: Use sclp_feat_check directly to read DIAG318 feature bit Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 10/13] s390x: Add test for STFLE interpretive execution (format-2) Janosch Frank
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Nina Schoetterl-Glausch, Christoph Schlameuss
From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Detect availability of alternate STFLE interpretive execution facilities
1 and 2.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Co-developed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
lib/s390x/sclp.c | 2 ++
lib/s390x/sclp.h | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/lib/s390x/sclp.c b/lib/s390x/sclp.c
index 9d9fd3cb..850cf432 100644
--- a/lib/s390x/sclp.c
+++ b/lib/s390x/sclp.c
@@ -162,11 +162,13 @@ void sclp_facilities_setup(void)
sclp_facilities.has_esop = sclp_feat_check(85, SCLP_FEAT_85_BIT_ESOP);
sclp_facilities.has_kss = sclp_feat_check(98, SCLP_FEAT_98_BIT_KSS);
sclp_facilities.has_cmma = sclp_feat_check(116, SCLP_FEAT_116_BIT_CMMA);
+ sclp_facilities.has_astfleie1 = sclp_feat_check(116, SCLP_FEAT_116_BIT_ASTFLEIE1);
sclp_facilities.has_64bscao = sclp_feat_check(116, SCLP_FEAT_116_BIT_64BSCAO);
sclp_facilities.has_esca = sclp_feat_check(116, SCLP_FEAT_116_BIT_ESCA);
sclp_facilities.has_ibs = sclp_feat_check(117, SCLP_FEAT_117_BIT_IBS);
sclp_facilities.has_pfmfi = sclp_feat_check(117, SCLP_FEAT_117_BIT_PFMFI);
sclp_facilities.has_diag318 = sclp_feat_check(134, SCLP_FEAT_134_BIT_DIAG318);
+ sclp_facilities.has_astfleie2 = sclp_feat_check(139, SCLP_FEAT_139_BIT_ASTFLEIE2);
for (i = 0; i < read_info->entries_cpu; i++, cpu++) {
/*
diff --git a/lib/s390x/sclp.h b/lib/s390x/sclp.h
index 87af429b..eb574350 100644
--- a/lib/s390x/sclp.h
+++ b/lib/s390x/sclp.h
@@ -129,9 +129,11 @@ struct sclp_facilities {
uint64_t has_cmma : 1;
uint64_t has_64bscao : 1;
uint64_t has_esca : 1;
+ uint64_t has_astfleie1 : 1;
uint64_t has_kss : 1;
uint64_t has_pfmfi : 1;
uint64_t has_ibs : 1;
+ uint64_t has_astfleie2 : 1;
};
/* bit number within a certain byte */
@@ -142,9 +144,11 @@ struct sclp_facilities {
#define SCLP_FEAT_116_BIT_64BSCAO 0
#define SCLP_FEAT_116_BIT_CMMA 1
#define SCLP_FEAT_116_BIT_ESCA 4
+#define SCLP_FEAT_116_BIT_ASTFLEIE1 7
#define SCLP_FEAT_117_BIT_PFMFI 1
#define SCLP_FEAT_117_BIT_IBS 2
#define SCLP_FEAT_134_BIT_DIAG318 0
+#define SCLP_FEAT_139_BIT_ASTFLEIE2 1
typedef struct ReadInfo {
SCCBHeader h;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 10/13] s390x: Add test for STFLE interpretive execution (format-2)
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (8 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 09/13] s390x: sclp: Add detection of alternate STFLE facilities Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 11/13] s390x: stsi: regression test for the STSI 3.2.2 count clamp Janosch Frank
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Christoph Schlameuss, Nina Schoetterl-Glausch
From: Christoph Schlameuss <schlameuss@linux.ibm.com>
The STFLE instruction indicates installed facilities.
SIE has facilities for the interpretive execution of STFLE.
There are multiple possible formats for the control block.
Use a snippet guest executing STFLE to get the result of
interpretive execution and check the result.
With the addition of the format-2 control block invalid format
specifiers are now possible.
Test for the occurrence of optional validity intercepts.
Move prefixes into main method to improve the readability of the
log by having prefixes for reports by tests called from multiple
places.
Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
lib/s390x/sie.c | 11 ++++++++
lib/s390x/sie.h | 1 +
s390x/stfle-sie.c | 72 +++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c
index ad1f2ade..99089dc3 100644
--- a/lib/s390x/sie.c
+++ b/lib/s390x/sie.c
@@ -43,6 +43,17 @@ void sie_check_validity(struct vm *vm, uint16_t vir_exp)
report(vir_exp == vir, "VALIDITY: %x", vir);
}
+void sie_check_optional_validity(struct vm *vm, uint16_t vir_exp)
+{
+ uint16_t vir = sie_get_validity(vm);
+
+ if (vir == 0xffff)
+ report_pass("optional VALIDITY: no");
+ else
+ report(vir_exp == vir, "optional VALIDITY: %x", vir);
+ vm->validity_expected = false;
+}
+
void sie_handle_validity(struct vm *vm)
{
if (vm->sblk->icptcode != ICPT_VALIDITY)
diff --git a/lib/s390x/sie.h b/lib/s390x/sie.h
index 85d691d5..e5970f36 100644
--- a/lib/s390x/sie.h
+++ b/lib/s390x/sie.h
@@ -51,6 +51,7 @@ void sie(struct vm *vm);
void sie_expect_validity(struct vm *vm);
uint16_t sie_get_validity(struct vm *vm);
void sie_check_validity(struct vm *vm, uint16_t vir_exp);
+void sie_check_optional_validity(struct vm *vm, uint16_t vir_exp);
void sie_handle_validity(struct vm *vm);
static inline bool sie_is_pv(struct vm *vm)
diff --git a/s390x/stfle-sie.c b/s390x/stfle-sie.c
index 8df1185c..3697e1ae 100644
--- a/s390x/stfle-sie.c
+++ b/s390x/stfle-sie.c
@@ -42,6 +42,7 @@ static struct guest_stfle_res run_guest(void)
uint64_t guest_stfle_addr;
uint64_t reg;
+ reset_guest(&vm);
sie(&vm);
assert(snippet_is_force_exit_value(&vm));
guest_stfle_addr = snippet_get_force_exit_value(&vm);
@@ -56,7 +57,6 @@ static void test_stfle_format_0(void)
{
struct guest_stfle_res res;
- report_prefix_push("format-0");
for (int j = 0; j < stfle_size(); j++)
WRITE_ONCE((*fac)[j], prng64(&prng_s));
vm.sblk->fac = (uint32_t)(uint64_t)fac;
@@ -64,6 +64,47 @@ static void test_stfle_format_0(void)
report(res.len == stfle_size(), "stfle len correct");
report(!memcmp(*fac, res.mem, res.len * sizeof(uint64_t)),
"Guest facility list as specified");
+}
+
+static void test_stfle_format_2(void)
+{
+ const int max_stfle_len = 8;
+ int guest_max_stfle_len = 0;
+ struct guest_stfle_res res;
+ bool saturated = false;
+
+ for (int i = 1; i <= max_stfle_len; i++) {
+ report_prefix_pushf("max STFLE len %d", i);
+
+ WRITE_ONCE((*fac)[0], i - 1);
+ for (int j = 0; j < i; j++)
+ WRITE_ONCE((*fac)[j + 1], prng64(&prng_s));
+ vm.sblk->fac = (uint32_t)(uint64_t)fac | 2;
+ res = run_guest();
+ /* len increases up to maximum (machine specific) */
+ if (res.len < i)
+ saturated = true;
+ if (saturated) {
+ report(res.len == guest_max_stfle_len, "stfle len correct");
+ } else {
+ report(res.len == i, "stfle len correct");
+ guest_max_stfle_len = i;
+ }
+ report(!memcmp(&(*fac)[1], res.mem, guest_max_stfle_len * sizeof(uint64_t)),
+ "Guest facility list as specified");
+
+ report_prefix_pop();
+ }
+}
+
+static void test_no_stfle_format(int format)
+{
+ report_prefix_pushf("no-stfle");
+ reset_guest(&vm);
+ vm.sblk->fac = (uint32_t)(uint64_t)fac | format;
+ sie_expect_validity(&vm);
+ sie(&vm);
+ sie_check_optional_validity(&vm, 0x1330);
report_prefix_pop();
}
@@ -119,20 +160,41 @@ static struct args parse_args(int argc, char **argv)
int main(int argc, char **argv)
{
struct args args = parse_args(argc, argv);
- bool run_format_0 = test_facility(7);
if (!sclp_facilities.has_sief2) {
report_skip("SIEF2 facility unavailable");
goto out;
}
- if (!run_format_0)
+ if (!test_facility(7)) {
report_skip("STFLE facility not available");
+ goto out;
+ }
report_info("PRNG seed: 0x%lx", args.seed);
prng_s = prng_init(args.seed);
setup_guest();
- if (run_format_0)
- test_stfle_format_0();
+
+ report_prefix_pushf("format-0");
+ test_stfle_format_0();
+ report_prefix_pop();
+
+ report_prefix_pushf("format-1");
+ if (!sclp_facilities.has_astfleie1)
+ test_no_stfle_format(1);
+ report_prefix_pop();
+
+ report_prefix_pushf("format-2");
+ if (!sclp_facilities.has_astfleie2) {
+ test_no_stfle_format(2);
+ report_skip("alternate STFLE interpretive-execution facility 2 not available");
+ } else {
+ test_stfle_format_2();
+ }
+ report_prefix_pop();
+
+ report_prefix_pushf("format-3");
+ test_no_stfle_format(3);
+ report_prefix_pop();
snippet_destroy_guest(&vm);
out:
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 11/13] s390x: stsi: regression test for the STSI 3.2.2 count clamp
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (9 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 10/13] s390x: Add test for STFLE interpretive execution (format-2) Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 12/13] s390x: unittests: Reenable tcg for migration tests Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 13/13] s390x: skey: Fence TCG protection checks Janosch Frank
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini
Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth,
Cornelia Huck
From: Christian Borntraeger <borntraeger@linux.ibm.com>
See https://lore.kernel.org/qemu-devel/20260622092035.400959-1-borntraeger@linux.ibm.com/
for the QEMU fix.
Add a regression test that races STSI 3.2.2 on one CPU against a second CPU
that continuously forces an out-of-range count value.
The out of bound access usually crashes/asserts QEMU with any sane
distribution build of QEMU, so its more or less guest root can kill itself.
We should test and fix nevertheless.
Testcase piggybacks on the existing stsi test, so some cases will be
tested twice. (with smp 1 and smp 2)
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
[frankja@linux.ibm.com: Merged the new unittests.cgf entry into old one]
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
s390x/stsi.c | 76 ++++++++++++++++++++++++++++++++++++++++++++-
s390x/unittests.cfg | 2 +-
2 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/s390x/stsi.c b/s390x/stsi.c
index 94a579dc..96361143 100644
--- a/s390x/stsi.c
+++ b/s390x/stsi.c
@@ -2,7 +2,7 @@
/*
* Store System Information tests
*
- * Copyright (c) 2019 IBM Corp
+ * Copyright IBM Corp. 2019,2026
*
* Authors:
* Janosch Frank <frankja@linux.ibm.com>
@@ -133,6 +133,79 @@ out:
report_prefix_pop();
}
+/*
+ * Number of STSI 3.2.2 calls raced against the count corruptor below.
+ * A memory write should be faster than an kvm->qemu exit, so 100 is
+ * good enough.
+ */
+#define RACE_ITERATIONS 100
+static u8 corrupt_count_value;
+
+static void count_corruptor(void)
+{
+ struct sysinfo_3_2_2 *data = (void *)pagebuf;
+
+ for (;;)
+ *(volatile u8 *)&data->count = corrupt_count_value;
+}
+
+/*
+ * Race STSI 3.2.2 on the boot CPU against a secondary CPU that continuously
+ * forces the given out-of-range value into the "count" field. Returns true
+ * if every STSI returned cc == 0, false on an unexpected condition code.
+ */
+static bool race_count_value(uint8_t value)
+{
+ int i, cc;
+
+ corrupt_count_value = value;
+ smp_cpu_setup(1, PSW_WITH_CUR_MASK(count_corruptor));
+
+ for (i = 0; i < RACE_ITERATIONS; i++) {
+ cc = stsi(pagebuf, 3, 2, 2);
+ if (cc) {
+ report_fail("count 0x%02x: unexpected cc %d on iteration %d",
+ value, cc, i);
+ break;
+ }
+ }
+
+ smp_cpu_stop(1);
+ smp_cpu_destroy(1);
+
+ return i == RACE_ITERATIONS;
+}
+
+/*
+ * The count value is 8 bit and valid values are 1-8 if stsi 3.2.2 is present.
+ * We test 0,9 as off-by-one, and 0xff as maximum value.
+ */
+static void test_3_2_2_race(void)
+{
+ report_prefix_push("3.2.2 count race");
+
+ if (stsi_get_fc() < 3) {
+ report_skip("Running under lpar, no level 3 to test.");
+ goto out;
+ }
+
+ if (smp_query_num_cpus() < 2) {
+ report_skip("Need at least 2 CPUs to race the count field.");
+ goto out;
+ }
+
+ if (race_count_value(0x0))
+ report_pass("host survived racing STSI 3.2.2 count 0x00");
+
+ if (race_count_value(0x9))
+ report_pass("host survived racing STSI 3.2.2 count 0x09");
+
+ if (race_count_value(0xff))
+ report_pass("host survived racing STSI 3.2.2 count 0xff");
+out:
+ report_prefix_pop();
+}
+
int main(void)
{
report_prefix_push("stsi");
@@ -140,5 +213,6 @@ int main(void)
test_specs();
test_fc();
test_3_2_2();
+ test_3_2_2_race();
return report_summary();
}
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index ed4d069e..8c39d4f1 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -79,7 +79,7 @@ qemu_params=-device diag288,id=watchdog0 --watchdog-action inject-nmi
[stsi]
file = stsi.elf
-qemu_params=-name kvm-unit-test --uuid 0fb84a86-727c-11ea-bc55-0242ac130003 -smp 1,maxcpus=8
+qemu_params=-name kvm-unit-test --uuid 0fb84a86-727c-11ea-bc55-0242ac130003 -smp 2,maxcpus=8
[smp]
file = smp.elf
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 12/13] s390x: unittests: Reenable tcg for migration tests
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (10 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 11/13] s390x: stsi: regression test for the STSI 3.2.2 count clamp Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 13/13] s390x: skey: Fence TCG protection checks Janosch Frank
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini; +Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth
The TCG fixes for this issue have been in QEMU for quite a while.
It's time to reenable these tests.
QEMU fix discussion:
https://lore.kernel.org/qemu-devel/20240312201458.79532-1-philmd@linaro.org/
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
s390x/unittests.cfg | 5 -----
1 file changed, 5 deletions(-)
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index 8c39d4f1..64bc998d 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -15,19 +15,14 @@ test_args = 'test 123'
[selftest-migration]
file = selftest-migration.elf
groups = selftest migration
-# TODO: Remove accel=kvm once the following TCG migration fix has been merged:
-# https://lore.kernel.org/qemu-devel/20240219061731.232570-1-npiggin@gmail.com/
-accel = kvm
[selftest-migration-skip]
file = selftest-migration.elf
groups = selftest migration
test_args = "skip"
-# This fails due to a QEMU TCG bug so KVM-only until QEMU is fixed upstream
[migration-memory]
file = memory-verify.elf
-accel = kvm
groups = migration
[intercept]
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [kvm-unit-tests GIT PULL 13/13] s390x: skey: Fence TCG protection checks
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
` (11 preceding siblings ...)
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 12/13] s390x: unittests: Reenable tcg for migration tests Janosch Frank
@ 2026-08-24 14:35 ` Janosch Frank
12 siblings, 0 replies; 14+ messages in thread
From: Janosch Frank @ 2026-08-24 14:35 UTC (permalink / raw)
To: pbonzini; +Cc: kvm, frankja, borntraeger, linux-s390, imbrenda, thuth
TCG does not implement the skey memory protection, skip those tests
under TCG instead of filtering them in the CI logs.
This way the test will PASS when run by humans and there's no
confusion why it fails anymore.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
s390x/skey.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/s390x/skey.c b/s390x/skey.c
index bb769730..1fc95857 100644
--- a/s390x/skey.c
+++ b/s390x/skey.c
@@ -14,6 +14,7 @@
#include <vmalloc.h>
#include <css.h>
#include <mmu.h>
+#include <hardware.h>
#include <asm/page.h>
#include <asm/facility.h>
#include <asm/mem.h>
@@ -736,6 +737,13 @@ int main(void)
test_set();
test_set_mb();
test_chg();
+
+ if (detect_host() == HOST_IS_TCG) {
+ report_skip("No actual access protection in TCG for skeys.");
+ report_prefix_pop();
+ return report_summary();
+ }
+
test_test_protection();
test_store_cpu_address();
test_diag_308();
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-08-24 14:38 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-24 14:35 [kvm-unit-tests GIT PULL 00/13] s390x: stflei test, fixes and sie lib rework Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 01/13] lib: s390x: Add function to get page root Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 02/13] lib: s390x: sie: Allocate physical guest memory via memalign Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 03/13] lib: s390x: sie: Memory rework Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 04/13] lib: s390x: snippet: Add function to create a guest of specific length Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 05/13] s390x: snippets: Add reset_guest() to lib Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 06/13] s390x: sclp: Remove unnecessary padding from struct sclp_facilities Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 07/13] s390x: sclp: Check sclp byte before reading feature bits Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 08/13] s390x: sclp: Use sclp_feat_check directly to read DIAG318 feature bit Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 09/13] s390x: sclp: Add detection of alternate STFLE facilities Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 10/13] s390x: Add test for STFLE interpretive execution (format-2) Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 11/13] s390x: stsi: regression test for the STSI 3.2.2 count clamp Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 12/13] s390x: unittests: Reenable tcg for migration tests Janosch Frank
2026-08-24 14:35 ` [kvm-unit-tests GIT PULL 13/13] s390x: skey: Fence TCG protection checks Janosch Frank
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox