···111111 preempt_enable();112112}113113114114+/**115115+ * stfle_size - Actual size of the facility list as specified by stfle116116+ * (number of double words)117117+ */118118+unsigned int stfle_size(void);119119+114120#endif /* __ASM_FACILITY_H */
+1-1
arch/s390/include/asm/kvm_host.h
···818818819819struct kvm_s390_cpu_model {820820 /* facility mask supported by kvm & hosting machine */821821- __u64 fac_mask[S390_ARCH_FAC_LIST_SIZE_U64];821821+ __u64 fac_mask[S390_ARCH_FAC_MASK_SIZE_U64];822822 struct kvm_s390_vm_cpu_subfunc subfuncs;823823 /* facility list requested by guest (in dma page) */824824 __u64 *fac_list;
···11+// SPDX-License-Identifier: GPL-2.022+/*33+ * Copyright IBM Corp. 202344+ */55+66+#include <asm/facility.h>77+88+unsigned int stfle_size(void)99+{1010+ static unsigned int size;1111+ unsigned int r;1212+ u64 dummy;1313+1414+ r = READ_ONCE(size);1515+ if (!r) {1616+ r = __stfle_asm(&dummy, 1) + 1;1717+ WRITE_ONCE(size, r);1818+ }1919+ return r;2020+}2121+EXPORT_SYMBOL(stfle_size);
+17-2
arch/s390/kvm/vsie.c
···1919#include <asm/nmi.h>2020#include <asm/dis.h>2121#include <asm/fpu/api.h>2222+#include <asm/facility.h>2223#include "kvm-s390.h"2324#include "gaccess.h"2425···985984static int handle_stfle(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)986985{987986 struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;988988- __u32 fac = READ_ONCE(vsie_page->scb_o->fac) & 0x7ffffff8U;987987+ __u32 fac = READ_ONCE(vsie_page->scb_o->fac);989988989989+ /*990990+ * Alternate-STFLE-Interpretive-Execution facilities are not supported991991+ * -> format-0 flcb992992+ */990993 if (fac && test_kvm_facility(vcpu->kvm, 7)) {991994 retry_vsie_icpt(vsie_page);995995+ /*996996+ * The facility list origin (FLO) is in bits 1 - 28 of the FLD997997+ * so we need to mask here before reading.998998+ */999999+ fac = fac & 0x7ffffff8U;10001000+ /*10011001+ * format-0 -> size of nested guest's facility list == guest's size10021002+ * guest's size == host's size, since STFLE is interpretatively executed10031003+ * using a format-0 for the guest, too.10041004+ */9921005 if (read_guest_real(vcpu, fac, &vsie_page->fac,993993- sizeof(vsie_page->fac)))10061006+ stfle_size() * sizeof(u64)))9941007 return set_validity_icpt(scb_s, 0x1090U);9951008 scb_s->fac = (__u32)(__u64) &vsie_page->fac;9961009 }