KVM: PPC: Book3S: Fix incorrect guest-to-user-translation error handling [Linux 4.19.70]

This Linux kernel change "KVM: PPC: Book3S: Fix incorrect guest-to-user-translation error handling" is included in the Linux 4.19.70 release. This change is authored by Alexey Kardashevskiy <aik [at] ozlabs.ru> on Tue Sep 3 16:16:27 2019 -0400. The commit for this change in Linux stable tree is db1841a (patch) which is from upstream commit ddfd151. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream ddfd151.

KVM: PPC: Book3S: Fix incorrect guest-to-user-translation error handling

[ Upstream commit ddfd151f3def9258397fcde7a372205a2d661903 ]

H_PUT_TCE_INDIRECT handlers receive a page with up to 512 TCEs from
a guest. Although we verify correctness of TCEs before we do anything
with the existing tables, there is a small window when a check in
kvmppc_tce_validate might pass and right after that the guest alters
the page of TCEs, causing an early exit from the handler and leaving
srcu_read_lock(&vcpu->kvm->srcu) (virtual mode) or lock_rmap(rmap)
(real mode) locked.

This fixes the bug by jumping to the common exit code with an appropriate
unlock.

Cc: stable@vger.kernel.org # v4.11+
Fixes: 121f80ba68f1 ("KVM: PPC: VFIO: Add in-kernel acceleration for VFIO")
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 12 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 arch/powerpc/kvm/book3s_64_vio.c    | 6 ++++--
 arch/powerpc/kvm/book3s_64_vio_hv.c | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 9a3f264..07a8004 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -602,8 +602,10 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,

        if (kvmppc_gpa_to_ua(vcpu->kvm,
                tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
-               &ua, NULL))
-           return H_PARAMETER;
+               &ua, NULL)) {
+           ret = H_PARAMETER;
+           goto unlock_exit;
+       }

        list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
            ret = kvmppc_tce_iommu_map(vcpu->kvm, stt,
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 6821ead..eb8b115 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -528,8 +528,10 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
        ua = 0;
        if (kvmppc_gpa_to_ua(vcpu->kvm,
                tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
-               &ua, NULL))
-           return H_PARAMETER;
+               &ua, NULL)) {
+           ret = H_PARAMETER;
+           goto unlock_exit;
+       }

        list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
            ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt,

Leave a Reply

Your email address will not be published. Required fields are marked *