summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Farman <farman@linux.ibm.com>2026-04-01 17:12:18 +0200
committerJanosch Frank <frankja@linux.ibm.com>2026-04-02 15:37:01 +0200
commitb0ad874d9852967dafdb94b1632e0732e01e6cd8 (patch)
tree951571e96489bf727bbbd5a36a146b625ab12201
parent1653545abc6835ab723c02697a5e2964e98e2c53 (diff)
KVM: s390: vsie: Allow non-zarch guests
Linux/KVM runs in z/Architecture-only mode. Although z/Architecture is built upon a long history of hardware refinements, any other CPU mode is not permitted. Allow a userspace to explicitly enable the use of ESA mode for nested guests, otherwise usage will be rejected. Reviewed-by: Janosch Frank <frankja@linux.ibm.com> Signed-off-by: Eric Farman <farman@linux.ibm.com> Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com> Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
-rw-r--r--arch/s390/include/asm/kvm_host.h1
-rw-r--r--arch/s390/kvm/vsie.c8
2 files changed, 6 insertions, 3 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 64a50f0862aa..b58faad8a7ce 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -656,6 +656,7 @@ struct kvm_arch {
int user_stsi;
int user_instr0;
int user_operexec;
+ int allow_vsie_esamode;
struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS];
wait_queue_head_t ipte_wq;
int ipte_lock_count;
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
index d249b10044eb..aa43c6848217 100644
--- a/arch/s390/kvm/vsie.c
+++ b/arch/s390/kvm/vsie.c
@@ -125,8 +125,8 @@ static int prepare_cpuflags(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
struct kvm_s390_sie_block *scb_o = vsie_page->scb_o;
int newflags, cpuflags = atomic_read(&scb_o->cpuflags);
- /* we don't allow ESA/390 guests */
- if (!(cpuflags & CPUSTAT_ZARCH))
+ /* we don't allow ESA/390 guests unless explicitly enabled */
+ if (!(cpuflags & CPUSTAT_ZARCH) && !vcpu->kvm->arch.allow_vsie_esamode)
return set_validity_icpt(scb_s, 0x0001U);
if (cpuflags & (CPUSTAT_RRF | CPUSTAT_MCDS))
@@ -135,7 +135,9 @@ static int prepare_cpuflags(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
return set_validity_icpt(scb_s, 0x0007U);
/* intervention requests will be set later */
- newflags = CPUSTAT_ZARCH;
+ newflags = 0;
+ if (cpuflags & CPUSTAT_ZARCH)
+ newflags = CPUSTAT_ZARCH;
if (cpuflags & CPUSTAT_GED && test_kvm_facility(vcpu->kvm, 8))
newflags |= CPUSTAT_GED;
if (cpuflags & CPUSTAT_GED2 && test_kvm_facility(vcpu->kvm, 78)) {