summaryrefslogtreecommitdiff
path: root/sys-kernel/gentoo-kernel/files/5.10.47-ppc64-kvm.patch
diff options
context:
space:
mode:
Diffstat (limited to 'sys-kernel/gentoo-kernel/files/5.10.47-ppc64-kvm.patch')
-rw-r--r--sys-kernel/gentoo-kernel/files/5.10.47-ppc64-kvm.patch56
1 files changed, 56 insertions, 0 deletions
diff --git a/sys-kernel/gentoo-kernel/files/5.10.47-ppc64-kvm.patch b/sys-kernel/gentoo-kernel/files/5.10.47-ppc64-kvm.patch
new file mode 100644
index 000000000000..59a7c7e75814
--- /dev/null
+++ b/sys-kernel/gentoo-kernel/files/5.10.47-ppc64-kvm.patch
@@ -0,0 +1,56 @@
+From 25edcc50d76c834479d11fcc7de46f3da4d95121 Mon Sep 17 00:00:00 2001
+From: Fabiano Rosas <farosas@linux.ibm.com>
+Date: Thu, 4 Feb 2021 17:05:17 -0300
+Subject: [PATCH] KVM: PPC: Book3S HV: Save and restore FSCR in the P9 path
+
+The Facility Status and Control Register is a privileged SPR that
+defines the availability of some features in problem state. Since it
+can be written by the guest, we must restore it to the previous host
+value after guest exit.
+
+This restoration is currently done by taking the value from
+current->thread.fscr, which in the P9 path is not enough anymore
+because the guest could context switch the QEMU thread, causing the
+guest-current value to be saved into the thread struct.
+
+The above situation manifested when running a QEMU linked against a
+libc with System Call Vectored support, which causes scv
+instructions to be run by QEMU early during the guest boot (during
+SLOF), at which point the FSCR is 0 due to guest entry. After a few
+scv calls (1 to a couple hundred), the context switching happens and
+the QEMU thread runs with the guest value, resulting in a Facility
+Unavailable interrupt.
+
+This patch saves and restores the host value of FSCR in the inner
+guest entry loop in a way independent of current->thread.fscr. The old
+way of doing it is still kept in place because it works for the old
+entry path.
+
+Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
+Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
+---
+ arch/powerpc/kvm/book3s_hv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
+index 89c686c17f0606..f6d470157fcb62 100644
+--- a/arch/powerpc/kvm/book3s_hv.c
++++ b/arch/powerpc/kvm/book3s_hv.c
+@@ -3611,6 +3611,7 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
+ unsigned long host_tidr = mfspr(SPRN_TIDR);
+ unsigned long host_iamr = mfspr(SPRN_IAMR);
+ unsigned long host_amr = mfspr(SPRN_AMR);
++ unsigned long host_fscr = mfspr(SPRN_FSCR);
+ s64 dec;
+ u64 tb;
+ int trap, save_pmu;
+@@ -3751,6 +3752,9 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
+ if (host_amr != vcpu->arch.amr)
+ mtspr(SPRN_AMR, host_amr);
+
++ if (host_fscr != vcpu->arch.fscr)
++ mtspr(SPRN_FSCR, host_fscr);
++
+ msr_check_and_set(MSR_FP | MSR_VEC | MSR_VSX);
+ store_fp_state(&vcpu->arch.fp);
+ #ifdef CONFIG_ALTIVEC