mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-27 13:22:47 -04:00
KVM: s390: vsie: Refactor handle_stfle
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> Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Message-ID: <20260612-vsie-alter-stfle-fac-v4-3-74f0e1559929@linux.ibm.com>
This commit is contained in:
committed by
Claudio Imbrenda
parent
a8ceca7d8c
commit
bf8f3cec93
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user