* [PATCH v3 1/4] KVM: s390: Minor refactor of base/ext facility lists
2026-06-11 15:54 [PATCH v3 0/4] KVM: s390: vsie: Implement ASTFLEIE facility 2 Christoph Schlameuss
@ 2026-06-11 15:54 ` Christoph Schlameuss
2026-06-11 15:54 ` [PATCH v3 2/4] s390/sclp: Detect ASTFLEIE 2 facility Christoph Schlameuss
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Christoph Schlameuss @ 2026-06-11 15:54 UTC (permalink / raw)
To: linux-s390
Cc: Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Hendrik Brueckner, Nina Schoetterl-Glausch, kvm,
Christoph Schlameuss
From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Directly use the size of the arrays instead of going through the
indirection of kvm_s390_fac_size().
Don't use magic number for the number of entries in the non hypervisor
managed facility bit mask list.
Make the constraint of that number on kvm_s390_fac_base obvious.
Get rid of implicit double anding of stfle_fac_list.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Co-developed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
---
arch/s390/kvm/kvm-s390.c | 44 +++++++++++++++++++-------------------------
1 file changed, 19 insertions(+), 25 deletions(-)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index ffb20a64d328..2a57ea095b48 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -232,33 +232,25 @@ static int async_destroy = 1;
module_param(async_destroy, int, 0444);
MODULE_PARM_DESC(async_destroy, "Asynchronous destroy for protected guests");
-/*
- * For now we handle at most 16 double words as this is what the s390 base
- * kernel handles and stores in the prefix page. If we ever need to go beyond
- * this, this requires changes to code, but the external uapi can stay.
- */
-#define SIZE_INTERNAL 16
-
+#define HMFAI_DWORDS 16
/*
* Base feature mask that defines default mask for facilities. Consists of the
* defines in FACILITIES_KVM and the non-hypervisor managed bits.
*/
-static unsigned long kvm_s390_fac_base[SIZE_INTERNAL] = { FACILITIES_KVM };
+static unsigned long kvm_s390_fac_base[HMFAI_DWORDS] = { FACILITIES_KVM };
+static_assert(ARRAY_SIZE(((long[]){ FACILITIES_KVM })) <= HMFAI_DWORDS);
+static_assert(ARRAY_SIZE(kvm_s390_fac_base) <= S390_ARCH_FAC_MASK_SIZE_U64);
+static_assert(ARRAY_SIZE(kvm_s390_fac_base) <= S390_ARCH_FAC_LIST_SIZE_U64);
+static_assert(ARRAY_SIZE(kvm_s390_fac_base) <= ARRAY_SIZE(stfle_fac_list));
+
/*
* Extended feature mask. Consists of the defines in FACILITIES_KVM_CPUMODEL
* and defines the facilities that can be enabled via a cpu model.
*/
-static unsigned long kvm_s390_fac_ext[SIZE_INTERNAL] = { FACILITIES_KVM_CPUMODEL };
-
-static unsigned long kvm_s390_fac_size(void)
-{
- BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_MASK_SIZE_U64);
- BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_LIST_SIZE_U64);
- BUILD_BUG_ON(SIZE_INTERNAL * sizeof(unsigned long) >
- sizeof(stfle_fac_list));
-
- return SIZE_INTERNAL;
-}
+static const unsigned long kvm_s390_fac_ext[] = { FACILITIES_KVM_CPUMODEL };
+static_assert(ARRAY_SIZE(kvm_s390_fac_ext) <= S390_ARCH_FAC_MASK_SIZE_U64);
+static_assert(ARRAY_SIZE(kvm_s390_fac_ext) <= S390_ARCH_FAC_LIST_SIZE_U64);
+static_assert(ARRAY_SIZE(kvm_s390_fac_ext) <= ARRAY_SIZE(stfle_fac_list));
/* available cpu features supported by kvm */
static DECLARE_BITMAP(kvm_s390_available_cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS);
@@ -3238,13 +3230,16 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm->arch.sie_page2->kvm = kvm;
kvm->arch.model.fac_list = kvm->arch.sie_page2->fac_list;
- for (i = 0; i < kvm_s390_fac_size(); i++) {
+ for (i = 0; i < ARRAY_SIZE(kvm_s390_fac_base); i++) {
kvm->arch.model.fac_mask[i] = stfle_fac_list[i] &
- (kvm_s390_fac_base[i] |
- kvm_s390_fac_ext[i]);
+ kvm_s390_fac_base[i];
kvm->arch.model.fac_list[i] = stfle_fac_list[i] &
kvm_s390_fac_base[i];
}
+ for (i = 0; i < ARRAY_SIZE(kvm_s390_fac_ext); i++) {
+ kvm->arch.model.fac_mask[i] |= stfle_fac_list[i] &
+ kvm_s390_fac_ext[i];
+ }
kvm->arch.model.subfuncs = kvm_s390_available_subfunc;
/* we are always in czam mode - even on pre z14 machines */
@@ -5820,9 +5815,8 @@ static int __init kvm_s390_init(void)
return -ENODEV;
}
- for (i = 0; i < 16; i++)
- kvm_s390_fac_base[i] |=
- stfle_fac_list[i] & nonhyp_mask(i);
+ for (i = 0; i < HMFAI_DWORDS; i++)
+ kvm_s390_fac_base[i] |= nonhyp_mask(i);
r = __kvm_s390_init();
if (r)
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v3 2/4] s390/sclp: Detect ASTFLEIE 2 facility
2026-06-11 15:54 [PATCH v3 0/4] KVM: s390: vsie: Implement ASTFLEIE facility 2 Christoph Schlameuss
2026-06-11 15:54 ` [PATCH v3 1/4] KVM: s390: Minor refactor of base/ext facility lists Christoph Schlameuss
@ 2026-06-11 15:54 ` Christoph Schlameuss
2026-06-11 15:54 ` [PATCH v3 3/4] KVM: s390: vsie: Refactor handle_stfle Christoph Schlameuss
2026-06-11 15:54 ` [PATCH v3 4/4] KVM: s390: vsie: Implement ASTFLEIE facility 2 Christoph Schlameuss
3 siblings, 0 replies; 6+ messages in thread
From: Christoph Schlameuss @ 2026-06-11 15:54 UTC (permalink / raw)
To: linux-s390
Cc: Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Hendrik Brueckner, Nina Schoetterl-Glausch, kvm,
Christoph Schlameuss
From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Detect alternate STFLE interpretive execution facility 2.
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>
---
arch/s390/include/asm/sclp.h | 1 +
drivers/s390/char/sclp_early.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index 0f184dbdbe5e..0f21501d3e86 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -104,6 +104,7 @@ struct sclp_info {
unsigned char has_aisii : 1;
unsigned char has_aeni : 1;
unsigned char has_aisi : 1;
+ unsigned char has_astfleie2 : 1;
unsigned int ibc;
unsigned int mtid;
unsigned int mtid_cp;
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
index 6bf501ad8ff0..22dd797e6229 100644
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -61,8 +61,10 @@ static void __init sclp_early_facilities_detect(void)
sclp.has_sipl = !!(sccb->cbl & 0x4000);
sclp.has_sipl_eckd = !!(sccb->cbl & 0x2000);
}
- if (sccb->cpuoff > 139)
+ if (sccb->cpuoff > 139) {
sclp.has_diag324 = !!(sccb->byte_139 & 0x80);
+ sclp.has_astfleie2 = !!(sccb->byte_139 & 0x40);
+ }
sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
sclp.rzm <<= 20;
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v3 3/4] KVM: s390: vsie: Refactor handle_stfle
2026-06-11 15:54 [PATCH v3 0/4] KVM: s390: vsie: Implement ASTFLEIE facility 2 Christoph Schlameuss
2026-06-11 15:54 ` [PATCH v3 1/4] KVM: s390: Minor refactor of base/ext facility lists Christoph Schlameuss
2026-06-11 15:54 ` [PATCH v3 2/4] s390/sclp: Detect ASTFLEIE 2 facility Christoph Schlameuss
@ 2026-06-11 15:54 ` Christoph Schlameuss
2026-06-11 15:54 ` [PATCH v3 4/4] KVM: s390: vsie: Implement ASTFLEIE facility 2 Christoph Schlameuss
3 siblings, 0 replies; 6+ messages in thread
From: Christoph Schlameuss @ 2026-06-11 15:54 UTC (permalink / raw)
To: linux-s390
Cc: Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Hendrik Brueckner, Nina Schoetterl-Glausch, kvm,
Christoph Schlameuss
From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Use switch case in anticipation of handling format-1 and format-2
facility list designations in the future.
As the alternate STFLE facilities are not enabled, only case 0 is
possible.
No functional change intended.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Co-developed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
---
arch/s390/include/uapi/asm/kvm.h | 1 +
arch/s390/kvm/vsie.c | 53 ++++++++++++++++++++++++++++------------
2 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
index 60345dd2cba2..4192769b5ce0 100644
--- a/arch/s390/include/uapi/asm/kvm.h
+++ b/arch/s390/include/uapi/asm/kvm.h
@@ -444,6 +444,7 @@ struct kvm_s390_vm_cpu_machine {
#define KVM_S390_VM_CPU_FEAT_PFMFI 11
#define KVM_S390_VM_CPU_FEAT_SIGPIF 12
#define KVM_S390_VM_CPU_FEAT_KSS 13
+#define KVM_S390_VM_CPU_FEAT_ASTFLEIE2 14
struct kvm_s390_vm_cpu_feat {
__u64 feat[16];
};
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
index e5a23f1c9749..c7dcdd460dd1 100644
--- a/arch/s390/kvm/vsie.c
+++ b/arch/s390/kvm/vsie.c
@@ -6,12 +6,15 @@
*
* Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
*/
+#include <linux/align.h>
#include <linux/vmalloc.h>
#include <linux/kvm_host.h>
#include <linux/bug.h>
+#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/sched/signal.h>
+#include <linux/stddef.h>
#include <linux/io.h>
#include <linux/mman.h>
@@ -1000,6 +1003,23 @@ static void retry_vsie_icpt(struct vsie_page *vsie_page)
clear_vsie_icpt(vsie_page);
}
+static int handle_stfle_0(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page,
+ u32 fac_list_origin)
+{
+ struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
+
+ /*
+ * format-0 -> size of nested guest's facility list == guest's size
+ * guest's size == host's size, since STFLE is interpretatively executed
+ * using a format-0 for the guest, too.
+ */
+ if (read_guest_real(vcpu, fac_list_origin, &vsie_page->fac,
+ stfle_size() * sizeof(u64)))
+ return set_validity_icpt(scb_s, 0x1090U);
+ scb_s->fac = (u32)virt_to_phys(&vsie_page->fac);
+ return 0;
+}
+
/*
* Try to shadow + enable the guest 2 provided facility list.
* Retry instruction execution if enabled for and provided by guest 2.
@@ -1009,29 +1029,30 @@ static void retry_vsie_icpt(struct vsie_page *vsie_page)
*/
static int handle_stfle(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
{
- struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
- __u32 fac = READ_ONCE(vsie_page->scb_o->fac);
+ bool has_astfleie2 = test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_ASTFLEIE2);
+ u32 fac = READ_ONCE(vsie_page->scb_o->fac);
+ int format_mask, format;
+ u32 origin;
+
+ BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct vsie_page, fac), 8));
- /*
- * Alternate-STFLE-Interpretive-Execution facilities are not supported
- * -> format-0 flcb
- */
if (fac && test_kvm_facility(vcpu->kvm, 7)) {
retry_vsie_icpt(vsie_page);
/*
* The facility list origin (FLO) is in bits 1 - 28 of the FLD
* so we need to mask here before reading.
*/
- fac = fac & 0x7ffffff8U;
- /*
- * format-0 -> size of nested guest's facility list == guest's size
- * guest's size == host's size, since STFLE is interpretatively executed
- * using a format-0 for the guest, too.
- */
- if (read_guest_real(vcpu, fac, &vsie_page->fac,
- stfle_size() * sizeof(u64)))
- return set_validity_icpt(scb_s, 0x1090U);
- scb_s->fac = (u32)virt_to_phys(&vsie_page->fac);
+ origin = fac & 0x7ffffff8U;
+ format_mask = has_astfleie2 ? 3 : 0;
+ format = fac & format_mask;
+ switch (format) {
+ case 0:
+ return handle_stfle_0(vcpu, vsie_page, origin);
+ case 1:
+ case 2:
+ case 3:
+ unreachable();
+ }
}
return 0;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v3 4/4] KVM: s390: vsie: Implement ASTFLEIE facility 2
2026-06-11 15:54 [PATCH v3 0/4] KVM: s390: vsie: Implement ASTFLEIE facility 2 Christoph Schlameuss
` (2 preceding siblings ...)
2026-06-11 15:54 ` [PATCH v3 3/4] KVM: s390: vsie: Refactor handle_stfle Christoph Schlameuss
@ 2026-06-11 15:54 ` Christoph Schlameuss
2026-06-11 16:08 ` sashiko-bot
3 siblings, 1 reply; 6+ messages in thread
From: Christoph Schlameuss @ 2026-06-11 15:54 UTC (permalink / raw)
To: linux-s390
Cc: Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Hendrik Brueckner, Nina Schoetterl-Glausch, kvm,
Christoph Schlameuss
From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Implement shadowing of format-2 facility list when running in VSIE.
ASTFLEIE2 is available since IBM z16.
To function G1 has to run this KVM code and G1 and G2 have to run QEMU
with ASTFLEIE2 support.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Co-developed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
---
arch/s390/include/asm/kvm_host.h | 7 +++++++
arch/s390/kvm/kvm-s390.c | 2 ++
arch/s390/kvm/vsie.c | 34 ++++++++++++++++++++++++++++++----
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 8a4f4a39f7a2..a4a7972ce79c 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -504,6 +504,13 @@ struct kvm_s390_cpu_model {
struct kvm_s390_vm_cpu_uv_feat uv_feat_guest;
};
+#define S390_ARCH_FAC_FORMAT_2 2
+struct kvm_s390_flcb2 {
+ u8 reserved0[7];
+ u8 length;
+ u64 facilities[S390_ARCH_FAC_LIST_SIZE_U64];
+};
+
typedef int (*crypto_hook)(struct kvm_vcpu *vcpu);
struct kvm_s390_crypto {
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 2a57ea095b48..cb623fc41127 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -460,6 +460,8 @@ static void __init kvm_s390_cpu_feat_init(void)
allow_cpu_feat(KVM_S390_VM_CPU_FEAT_IBS);
if (sclp.has_kss)
allow_cpu_feat(KVM_S390_VM_CPU_FEAT_KSS);
+ if (sclp.has_astfleie2)
+ allow_cpu_feat(KVM_S390_VM_CPU_FEAT_ASTFLEIE2);
/*
* KVM_S390_VM_CPU_FEAT_SKEY: Wrong shadow of PTE.I bits will make
* all skey handling functions read/set the skey from the PGSTE
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
index c7dcdd460dd1..9a9a6d8b8ffc 100644
--- a/arch/s390/kvm/vsie.c
+++ b/arch/s390/kvm/vsie.c
@@ -65,9 +65,9 @@ struct vsie_page {
gpa_t scb_gpa; /* 0x0258 */
/* the shadow gmap in use by the vsie_page */
struct gmap_cache gmap_cache; /* 0x0260 */
- __u8 reserved[0x0700 - 0x0278]; /* 0x0278 */
- struct kvm_s390_crypto_cb crycb; /* 0x0700 */
- __u8 fac[S390_ARCH_FAC_LIST_SIZE_BYTE]; /* 0x0800 */
+ __u8 reserved[0x06f8 - 0x0278]; /* 0x0278 */
+ struct kvm_s390_crypto_cb crycb; /* 0x06f8 */
+ __u8 fac[8 + S390_ARCH_FAC_LIST_SIZE_BYTE];/* 0x0800 */
};
static_assert(sizeof(struct vsie_page) == PAGE_SIZE);
@@ -1020,6 +1020,28 @@ static int handle_stfle_0(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page,
return 0;
}
+static int handle_stfle_2(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page, u32 fac_list_origin)
+{
+ struct kvm_s390_flcb2 *flcb_s = (struct kvm_s390_flcb2 *)vsie_page->fac;
+ struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
+ u64 len;
+
+ if (read_guest_real(vcpu, fac_list_origin, &len, sizeof(len)))
+ return set_validity_icpt(scb_s, 0x1090U);
+
+ /* discard reserved bits */
+ len = (len & U8_MAX);
+ flcb_s->length = len;
+ len += 1;
+
+ if (read_guest_real(vcpu, fac_list_origin + offsetof(struct kvm_s390_flcb2, facilities),
+ &flcb_s->facilities, len * sizeof(u64)))
+ return set_validity_icpt(scb_s, 0x1090U);
+
+ scb_s->fac = (u32)virt_to_phys(&vsie_page->fac) | S390_ARCH_FAC_FORMAT_2;
+ return 0;
+}
+
/*
* Try to shadow + enable the guest 2 provided facility list.
* Retry instruction execution if enabled for and provided by guest 2.
@@ -1034,6 +1056,8 @@ static int handle_stfle(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
int format_mask, format;
u32 origin;
+ /* assert no overflow with maximum len */
+ BUILD_BUG_ON(sizeof(vsie_page->fac) < ((S390_ARCH_FAC_LIST_SIZE_U64 + 1) * sizeof(u64)));
BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct vsie_page, fac), 8));
if (fac && test_kvm_facility(vcpu->kvm, 7)) {
@@ -1049,9 +1073,11 @@ static int handle_stfle(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
case 0:
return handle_stfle_0(vcpu, vsie_page, origin);
case 1:
+ return set_validity_icpt(&vsie_page->scb_s, 0x1330U);
case 2:
+ return handle_stfle_2(vcpu, vsie_page, origin);
case 3:
- unreachable();
+ return set_validity_icpt(&vsie_page->scb_s, 0x1330U);
}
}
return 0;
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v3 4/4] KVM: s390: vsie: Implement ASTFLEIE facility 2
2026-06-11 15:54 ` [PATCH v3 4/4] KVM: s390: vsie: Implement ASTFLEIE facility 2 Christoph Schlameuss
@ 2026-06-11 16:08 ` sashiko-bot
0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-06-11 16:08 UTC (permalink / raw)
To: Christoph Schlameuss
Cc: Heiko Carstens, linux-s390, Vasily Gorbik, Alexander Gordeev, kvm
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] Hardware alignment violation for Cryptographic Control Block (CRYCB) Format 2.
- [High] Uninitialized `reserved0` field in the shadow format-2 facility list control block leads to hardware state corruption.
--
commit 74d49835ae9f08ad6c33a2e48ab3b975fa0b0159
Author: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
KVM: s390: vsie: Implement ASTFLEIE facility 2
This commit implements shadowing of the format-2 facility list when
running in VSIE, to support the ASTFLEIE2 facility available since
IBM z16.
> diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
> index 2ea3bbaf568e5..592d6b6f57292 100644
> --- a/arch/s390/kvm/vsie.c
> +++ b/arch/s390/kvm/vsie.c
> @@ -65,9 +65,9 @@ struct vsie_page {
> gpa_t scb_gpa; /* 0x0258 */
> /* the shadow gmap in use by the vsie_page */
> struct gmap_cache gmap_cache; /* 0x0260 */
> - __u8 reserved[0x0700 - 0x0278]; /* 0x0278 */
> - struct kvm_s390_crypto_cb crycb; /* 0x0700 */
> - __u8 fac[S390_ARCH_FAC_LIST_SIZE_BYTE]; /* 0x0800 */
> + __u8 reserved[0x06f8 - 0x0278]; /* 0x0278 */
> + struct kvm_s390_crypto_cb crycb; /* 0x06f8 */
[Severity: Critical]
Does moving crycb to offset 0x06f8 violate the hardware's 256-byte
alignment requirement for the Cryptographic Control Block (CRYCB) Origin
address?
When KVM applies CRYCB_FORMAT2 to this unaligned physical address in
shadow_crycb():
scb_s->crycbd = (u32)virt_to_phys(&vsie_page->crycb) | CRYCB_FORMAT2;
will the hardware see a misaligned crycbd value and either inject a
validity intercept or mask out the lower bits, reading keys from
uninitialized padding instead of the actual control block?
[ ... ]
> @@ -999,6 +999,28 @@ static int handle_stfle_0(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page,
> return 0;
> }
>
> +static int handle_stfle_2(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page, u32 fac_list_origin)
> +{
> + struct kvm_s390_flcb2 *flcb_s = (struct kvm_s390_flcb2 *)vsie_page->fac;
> + struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
> + u64 len;
> +
> + if (read_guest_real(vcpu, fac_list_origin, &len, sizeof(len)))
> + return set_validity_icpt(scb_s, 0x1090U);
> +
> + /* discard reserved bits */
> + len = (len & U8_MAX);
> + flcb_s->length = len;
> + len += 1;
[Severity: High]
Could this leave the 7-byte reserved0 array in the shadow format-2
facility list uninitialized?
Since vsie_page structures are pooled and reused across nested executions
without zeroing the fac array, will reserved0 contain stale data from
previous executions, like facility bits from a prior format-0 STFLE
execution?
If the architecture requires these reserved bits to be zero, will passing
non-zero reserved bits to the hardware cause a validity intercept and
crash the nested guest?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260611-vsie-alter-stfle-fac-v3-0-b1a35efedaba@linux.ibm.com?part=4
^ permalink raw reply [flat|nested] 6+ messages in thread