public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	kvm@vger.kernel.org
Cc: Joey Gouly <joey.gouly@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Oliver Upton <oupton@kernel.org>,
	Zenghui Yu <yuzenghui@huawei.com>, Fuad Tabba <tabba@google.com>,
	Will Deacon <will@kernel.org>,
	Quentin Perret <qperret@google.com>
Subject: Re: [PATCH v2 21/30] KVM: arm64: Kill topup_memcache from kvm_s2_fault
Date: Fri, 27 Mar 2026 14:49:11 +0000	[thread overview]
Message-ID: <86ecl549aw.wl-maz@kernel.org> (raw)
In-Reply-To: <20260327113618.4051534-22-maz@kernel.org>

On Fri, 27 Mar 2026 11:36:09 +0000,
Marc Zyngier <maz@kernel.org> wrote:
> 
> The topup_memcache field can be easily replaced by the equivalent
> conditions, and the resulting code is not much worse.
> 
> Tested-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/kvm/mmu.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index e8bda71e862b2..5b05caecdbd92 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1712,7 +1712,6 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
>  
>  struct kvm_s2_fault {
>  	bool writable;
> -	bool topup_memcache;
>  	bool mte_allowed;
>  	bool is_vma_cacheable;
>  	bool s2_force_noncacheable;
> @@ -1983,9 +1982,8 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
>  		.logging_active = logging_active,
>  		.force_pte = logging_active,
>  		.prot = KVM_PGTABLE_PROT_R,
> -		.topup_memcache = !perm_fault || (logging_active && kvm_is_write_fault(s2fd->vcpu)),
>  	};
> -	void *memcache;
> +	void *memcache = NULL;
>  	int ret;
>  
>  	/*
> @@ -1994,9 +1992,11 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
>  	 * 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.
>  	 */
> -	ret = prepare_mmu_memcache(s2fd->vcpu, fault.topup_memcache, &memcache);
> -	if (ret)
> -		return ret;
> +	if (!perm_fault || (logging_active && kvm_is_write_fault(s2fd->vcpu))) {
> +		ret = prepare_mmu_memcache(s2fd->vcpu, true, &memcache);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	/*
>  	 * Let's check if we will get back a huge page backed by hugetlbfs, or

Sashiko has spotted [1] an interesting corner case here, which is that the
original code always initialises memcache to its correct value, while
we now only do it in a limited number of cases.

I'm proposing to restore the original behaviour by folding the
following change into this patch, splitting the retrieval of the
memcache pointer from the top-up and avoiding the ugly pointer
indirection:

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 1fe7182be45ac..03e1f389339c7 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1513,25 +1513,22 @@ static bool kvm_vma_is_cacheable(struct vm_area_struct *vma)
 	}
 }
 
-static int prepare_mmu_memcache(struct kvm_vcpu *vcpu, bool topup_memcache,
-				void **memcache)
+static void *get_mmu_memcache(struct kvm_vcpu *vcpu)
 {
-	int min_pages;
-
 	if (!is_protected_kvm_enabled())
-		*memcache = &vcpu->arch.mmu_page_cache;
+		return &vcpu->arch.mmu_page_cache;
 	else
-		*memcache = &vcpu->arch.pkvm_memcache;
-
-	if (!topup_memcache)
-		return 0;
+		return &vcpu->arch.pkvm_memcache;
+}
 
-	min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu);
+static int topup_mmu_memcache(struct kvm_vcpu *vcpu, void *memcache)
+{
+	int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu);
 
 	if (!is_protected_kvm_enabled())
-		return kvm_mmu_topup_memory_cache(*memcache, min_pages);
+		return kvm_mmu_topup_memory_cache(memcache, min_pages);
 
-	return topup_hyp_memcache(*memcache, min_pages);
+	return topup_hyp_memcache(memcache, min_pages);
 }
 
 /*
@@ -1589,7 +1586,8 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
 	gfn_t gfn;
 	int ret;
 
-	ret = prepare_mmu_memcache(s2fd->vcpu, true, &memcache);
+	memcache = get_mmu_memcache(s2fd->vcpu);
+	ret = topup_mmu_memcache(s2fd->vcpu, memcache);
 	if (ret)
 		return ret;
 
@@ -1993,7 +1991,7 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
 	bool perm_fault = kvm_vcpu_trap_is_permission_fault(s2fd->vcpu);
 	struct kvm_s2_fault_vma_info s2vi = {};
 	enum kvm_pgtable_prot prot;
-	void *memcache = NULL;
+	void *memcache;
 	int ret;
 
 	/*
@@ -2002,9 +2000,10 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
 	 * 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.
 	 */
+	memcache = get_mmu_memcache(s2fd->vcpu);
 	if (!perm_fault || (memslot_is_logging(s2fd->memslot) &&
 			    kvm_is_write_fault(s2fd->vcpu))) {
-		ret = prepare_mmu_memcache(s2fd->vcpu, true, &memcache);
+		ret = topup_mmu_memcache(s2fd->vcpu, memcache);
 		if (ret)
 			return ret;
 	}

The bot has also pointed out a couple of cases where memcache and
permission faults interact badly. I'll look into them separately, as
they predate this rework.

Thanks,

	M.

[1] https://sashiko.dev/#/patchset/20260327113618.4051534-1-maz%40kernel.org?patch=12134

-- 
Without deviation from the norm, progress is not possible.


  reply	other threads:[~2026-03-27 14:49 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-27 11:35 [PATCH v2 00/30] KVM: arm64: Combined user_mem_abort() rework Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 01/30] KVM: arm64: Extract VMA size resolution in user_mem_abort() Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 02/30] KVM: arm64: Introduce struct kvm_s2_fault to user_mem_abort() Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 03/30] KVM: arm64: Extract PFN resolution in user_mem_abort() Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 04/30] KVM: arm64: Isolate mmap_read_lock inside new kvm_s2_fault_get_vma_info() helper Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 05/30] KVM: arm64: Extract stage-2 permission logic in user_mem_abort() Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 06/30] KVM: arm64: Extract page table mapping " Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 07/30] KVM: arm64: Simplify nested VMA shift calculation Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 08/30] KVM: arm64: Remove redundant state variables from struct kvm_s2_fault Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 09/30] KVM: arm64: Simplify return logic in user_mem_abort() Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 10/30] KVM: arm64: Initialize struct kvm_s2_fault completely at declaration Marc Zyngier
2026-03-27 11:35 ` [PATCH v2 11/30] KVM: arm64: Optimize early exit checks in kvm_s2_fault_pin_pfn() Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 12/30] KVM: arm64: Hoist MTE validation check out of MMU lock path Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 13/30] KVM: arm64: Clean up control flow in kvm_s2_fault_map() Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 14/30] KVM: arm64: Kill fault->ipa Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 15/30] KVM: arm64: Make fault_ipa immutable Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 16/30] KVM: arm64: Move fault context to const structure Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 17/30] KVM: arm64: Replace fault_is_perm with a helper Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 18/30] KVM: arm64: Constrain fault_granule to kvm_s2_fault_map() Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 19/30] KVM: arm64: Kill write_fault from kvm_s2_fault Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 20/30] KVM: arm64: Kill exec_fault " Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 21/30] KVM: arm64: Kill topup_memcache " Marc Zyngier
2026-03-27 14:49   ` Marc Zyngier [this message]
2026-03-27 11:36 ` [PATCH v2 22/30] KVM: arm64: Move VMA-related information to kvm_s2_fault_vma_info Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 23/30] KVM: arm64: Kill logging_active from kvm_s2_fault Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 24/30] KVM: arm64: Restrict the scope of the 'writable' attribute Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 25/30] KVM: arm64: Move kvm_s2_fault.{pfn,page} to kvm_s2_vma_info Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 26/30] KVM: arm64: Replace force_pte with a max_map_size attribute Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 27/30] KVM: arm64: Move device mapping management into kvm_s2_fault_pin_pfn() Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 28/30] KVM: arm64: Directly expose mapping prot and kill kvm_s2_fault Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 29/30] KVM: arm64: Simplify integration of adjust_nested_*_perms() Marc Zyngier
2026-03-27 11:36 ` [PATCH v2 30/30] KVM: arm64: Convert gmem_abort() to struct kvm_s2_fault_desc Marc Zyngier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=86ecl549aw.wl-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=oupton@kernel.org \
    --cc=qperret@google.com \
    --cc=suzuki.poulose@arm.com \
    --cc=tabba@google.com \
    --cc=will@kernel.org \
    --cc=yuzenghui@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox