From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EADD312831; Tue, 25 Aug 2026 14:01:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787666500; cv=none; b=RpB0PieptowxoV9AQeZpt+/JdI+9VVD+HRBaPXIV3/ubAxKvuSs+axW1NHwzMucTT+9GlzsAW31SSYeWirByWZVnvQJ72CA3DU5xzANhyeHRejh4oFwvUde0BHxitmhXy5ppXMdciPfWEKkYIgwtjQcYQxJyc5ohQeIvLDguRlY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787666500; c=relaxed/simple; bh=T83tOZkWRCzxijIPJ8Fed9XOxue6u3pLH03vbhcSMi0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BI9zzUBHLm5rBJGOxrWwwauRP2VqWwx7ztvp69SROeGfJSDkbgHKypFv4+gouJrlidHcy1p9x+qztSHp08YyxGWTjsTIPu74tIefOBk9Q8uGW03yWkoANeaYvTSbYoFtX0C9hF9H0FslFYdI/2wBzkFywHY/yF5F1iwiwcTvMGQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=AGc8ykDc; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="AGc8ykDc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB6101F000E9; Tue, 25 Aug 2026 14:01:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1787666499; bh=/fNJ9WKiikCCtGfbP4N6I3R2sryeE/5Csb/9uhhAptE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=AGc8ykDc6f+AR7m+IusCwKF+XVFj/gemEuMRMyfOOQyTHdK6o+SSY4mwKwl4SLfS7 HDB9h2MxgqK0/nDA8kCtPlP4sYD15bFzgtu+/OUiwaAClAObOwlztGqPmxjVUzzJ5B 3eKai4rfUQYJAbSAs33uePIUpRXHm80NnB13jfq4= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Sean Christopherson , David Matlack , Marc Zyngier , Oliver Upton , Bjoern Doebel Subject: [PATCH 5.10 28/57] KVM: arm64: Retry fault if vma_lookup() results become invalid Date: Tue, 25 Aug 2026 15:26:50 +0200 Message-ID: <20260825132542.417175227@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825132541.342390421@linuxfoundation.org> References: <20260825132541.342390421@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: David Matlack commit 13ec9308a85702af7c31f3638a2720863848a7f2 upstream. Read mmu_invalidate_seq before dropping the mmap_lock so that KVM can detect if the results of vma_lookup() (e.g. vma_shift) become stale before it acquires kvm->mmu_lock. This fixes a theoretical bug where a VMA could be changed by userspace after vma_lookup() and before KVM reads the mmu_invalidate_seq, causing KVM to install page table entries based on a (possibly) no-longer-valid vma_shift. Re-order the MMU cache top-up to earlier in user_mem_abort() so that it is not done after KVM has read mmu_invalidate_seq (i.e. so as to avoid inducing spurious fault retries). This bug has existed since KVM/ARM's inception. It's unlikely that any sane userspace currently modifies VMAs in such a way as to trigger this race. And even with directed testing I was unable to reproduce it. But a sufficiently motivated host userspace might be able to exploit this race. Fixes: 94f8e6418d39 ("KVM: ARM: Handle guest faults in KVM") Cc: stable@vger.kernel.org Reported-by: Sean Christopherson Signed-off-by: David Matlack Reviewed-by: Marc Zyngier Link: https://lore.kernel.org/r/20230313235454.2964067-1-dmatlack@google.com Signed-off-by: Oliver Upton [doebel: adjust to contextual and naming differences in 5.10] Signed-off-by: Bjoern Doebel Signed-off-by: Greg Kroah-Hartman --- arch/arm64/kvm/mmu.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -769,6 +769,19 @@ static int user_mem_abort(struct kvm_vcp return -EFAULT; } + /* + * Permission faults just need to update the existing leaf entry, + * and so normally don't require allocations from the memcache. The + * only exception to this is when dirty logging is enabled at runtime + * and a write fault needs to collapse a block entry into a table. + */ + if (fault_status != FSC_PERM || (logging_active && write_fault)) { + ret = kvm_mmu_topup_memory_cache(memcache, + kvm_mmu_cache_min_pages(kvm)); + if (ret) + return ret; + } + /* Let's check if we will get back a huge page backed by hugetlbfs */ mmap_read_lock(current->mm); vma = find_vma_intersection(current->mm, hva, hva + 1); @@ -818,32 +831,17 @@ static int user_mem_abort(struct kvm_vcp fault_ipa &= ~(vma_pagesize - 1); gfn = fault_ipa >> PAGE_SHIFT; - mmap_read_unlock(current->mm); /* - * Permission faults just need to update the existing leaf entry, - * and so normally don't require allocations from the memcache. The - * only exception to this is when dirty logging is enabled at runtime - * and a write fault needs to collapse a block entry into a table. + * Read mmu_notifier_seq so that KVM can detect if the results of + * find_vma_intersection() or gfn_to_pfn_prot() become stale prior to + * acquiring kvm->mmu_lock. + * + * Rely on mmap_read_unlock() for an implicit smp_rmb(), which pairs + * with the smp_wmb() in kvm_mmu_notifier_invalidate_range_end(). */ - if (fault_status != FSC_PERM || (logging_active && write_fault)) { - ret = kvm_mmu_topup_memory_cache(memcache, - kvm_mmu_cache_min_pages(kvm)); - if (ret) - return ret; - } - mmu_seq = vcpu->kvm->mmu_notifier_seq; - /* - * Ensure the read of mmu_notifier_seq happens before we call - * gfn_to_pfn_prot (which calls get_user_pages), so that we don't risk - * the page we just got a reference to gets unmapped before we have a - * chance to grab the mmu_lock, which ensure that if the page gets - * unmapped afterwards, the call to kvm_unmap_hva will take it away - * from us again properly. This smp_rmb() interacts with the smp_wmb() - * in kvm_mmu_notifier_invalidate_. - */ - smp_rmb(); + mmap_read_unlock(current->mm); pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable); if (pfn == KVM_PFN_ERR_HWPOISON) {