mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02: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:
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_PFMFI 11
|
||||||
#define KVM_S390_VM_CPU_FEAT_SIGPIF 12
|
#define KVM_S390_VM_CPU_FEAT_SIGPIF 12
|
||||||
#define KVM_S390_VM_CPU_FEAT_KSS 13
|
#define KVM_S390_VM_CPU_FEAT_KSS 13
|
||||||
|
#define KVM_S390_VM_CPU_FEAT_ASTFLEIE2 14
|
||||||
struct kvm_s390_vm_cpu_feat {
|
struct kvm_s390_vm_cpu_feat {
|
||||||
__u64 feat[16];
|
__u64 feat[16];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,15 @@
|
||||||
*
|
*
|
||||||
* Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
|
* Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
|
||||||
*/
|
*/
|
||||||
|
#include <linux/align.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/kvm_host.h>
|
#include <linux/kvm_host.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/bitmap.h>
|
#include <linux/bitmap.h>
|
||||||
#include <linux/sched/signal.h>
|
#include <linux/sched/signal.h>
|
||||||
|
#include <linux/stddef.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/mman.h>
|
#include <linux/mman.h>
|
||||||
|
|
||||||
|
|
@ -1000,6 +1003,23 @@ static void retry_vsie_icpt(struct vsie_page *vsie_page)
|
||||||
clear_vsie_icpt(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.
|
* Try to shadow + enable the guest 2 provided facility list.
|
||||||
* Retry instruction execution if enabled for and provided by guest 2.
|
* 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)
|
static int handle_stfle(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
||||||
{
|
{
|
||||||
struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
|
bool has_astfleie2 = test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_ASTFLEIE2);
|
||||||
__u32 fac = READ_ONCE(vsie_page->scb_o->fac);
|
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)) {
|
if (fac && test_kvm_facility(vcpu->kvm, 7)) {
|
||||||
retry_vsie_icpt(vsie_page);
|
retry_vsie_icpt(vsie_page);
|
||||||
/*
|
/*
|
||||||
* The facility list origin (FLO) is in bits 1 - 28 of the FLD
|
* The facility list origin (FLO) is in bits 1 - 28 of the FLD
|
||||||
* so we need to mask here before reading.
|
* so we need to mask here before reading.
|
||||||
*/
|
*/
|
||||||
fac = fac & 0x7ffffff8U;
|
origin = fac & 0x7ffffff8U;
|
||||||
/*
|
format_mask = has_astfleie2 ? 3 : 0;
|
||||||
* format-0 -> size of nested guest's facility list == guest's size
|
format = fac & format_mask;
|
||||||
* guest's size == host's size, since STFLE is interpretatively executed
|
switch (format) {
|
||||||
* using a format-0 for the guest, too.
|
case 0:
|
||||||
*/
|
return handle_stfle_0(vcpu, vsie_page, origin);
|
||||||
if (read_guest_real(vcpu, fac, &vsie_page->fac,
|
case 1:
|
||||||
stfle_size() * sizeof(u64)))
|
case 2:
|
||||||
return set_validity_icpt(scb_s, 0x1090U);
|
case 3:
|
||||||
scb_s->fac = (u32)virt_to_phys(&vsie_page->fac);
|
unreachable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user