From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EE8D4EE36AC for ; Thu, 12 Feb 2026 17:22:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=kjGxktMIltht+iMJN2QFZidRJKEy+kLFfTaOz5Rtafs=; b=psvhZD25ehHEuMDvCGwMtitHEu 5uNN2oVDNJwZvqTB8m6X5PPku8iZStUkwh7TeekYBW9EzOvVjk18azoJesXbrjFIxB9Og1b6i0kFb 67dQHScpxc2ZTfCrnFjMnLj3DZsI6IKqfxLwdTiZhTJhRD9V4Sr+iemzHfBSuO6OlcR42JB1Ld9wV Sz5VC6CceiAEgZGM8B/vFLvfW/N2fB07QCAj0DKRwXlw/93YswqMuAcHdCkdYjtumHuvS2XwkS6Eg u24aXGGB4MXKSTKZnUeRMdpGOKxYv3scHHS+e4EbE2v9D+c6/fJz/xQ61HNIglaeEhIAyiuz+02bN PHW3gMig==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1vqaOo-00000002Qtv-0amn; Thu, 12 Feb 2026 17:22:42 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1vqaOj-00000002QtU-0SuR for linux-arm-kernel@lists.infradead.org; Thu, 12 Feb 2026 17:22:40 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 68F49339; Thu, 12 Feb 2026 09:22:29 -0800 (PST) Received: from raptor (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DA21E3F632; Thu, 12 Feb 2026 09:22:32 -0800 (PST) Date: Thu, 12 Feb 2026 17:22:28 +0000 From: Alexandru Elisei To: Will Deacon Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Quentin Perret , Fuad Tabba , Vincent Donnefort , Mostafa Saleh Subject: Re: [PATCH v2 25/35] KVM: arm64: Reclaim faulting page from pKVM in spurious fault handler Message-ID: References: <20260119124629.2563-1-will@kernel.org> <20260119124629.2563-26-will@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260119124629.2563-26-will@kernel.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260212_092237_257955_1562E7D7 X-CRM114-Status: GOOD ( 27.17 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Hi Will, Would be nice to merge this with the previous patch, that added the force reclaim function, as it would make reviewing easier. On Mon, Jan 19, 2026 at 12:46:18PM +0000, Will Deacon wrote: > Host kernel accesses to pages that are inaccessible at stage-2 result in > the injection of a translation fault, which is fatal unless an exception > table fixup is registered for the faulting PC (e.g. for user access > routines). This is undesirable, since a get_user_pages() call could be > used to obtain a reference to a donated page and then a subsequent > access via a kernel mapping would lead to a panic(). > > Rework the spurious fault handler so that stage-2 faults injected back > into the host result in the target page being forcefully reclaimed when > no exception table fixup handler is registered. > > Signed-off-by: Will Deacon > --- > arch/arm64/include/asm/virt.h | 6 ++++++ > arch/arm64/kvm/pkvm.c | 7 +++++++ > arch/arm64/mm/fault.c | 15 +++++++++------ > 3 files changed, 22 insertions(+), 6 deletions(-) > > diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h > index b51ab6840f9c..e80addc923a4 100644 > --- a/arch/arm64/include/asm/virt.h > +++ b/arch/arm64/include/asm/virt.h > @@ -94,6 +94,12 @@ static inline bool is_pkvm_initialized(void) > static_branch_likely(&kvm_protected_mode_initialized); > } > > +#ifdef CONFIG_KVM > +bool pkvm_reclaim_guest_page(phys_addr_t phys); > +#else > +static inline bool pkvm_reclaim_guest_page(phys_addr_t phys) { return false; } > +#endif > + > /* Reports the availability of HYP mode */ > static inline bool is_hyp_mode_available(void) > { > diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c > index 8be91051699e..d1926cb08c76 100644 > --- a/arch/arm64/kvm/pkvm.c > +++ b/arch/arm64/kvm/pkvm.c > @@ -563,3 +563,10 @@ int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size, > WARN_ON_ONCE(1); > return -EINVAL; > } > + > +bool pkvm_reclaim_guest_page(phys_addr_t phys) > +{ > + int ret = kvm_call_hyp_nvhe(__pkvm_force_reclaim_guest_page, phys); Nitpicking here, we have the functions __pkvm_reclaim_page_guest() and this function, pkvm_reclaim_guest_page(), which calls __pkvm_force_reclaim_guest_page, which in turn calls __pkvm_host_force_reclaim_page_guest(). I think having a bit of naming consistency would be really useful when navigating the source code. It might also be useful to document that callers of the hypercall __pkvm_force_reclaim_guest_page are not expected to unpin the page in case of success, but callers of __pkvm_reclaim_dying_guest_page are. Thanks, Alex > + > + return !ret || ret == -EAGAIN; > +} > diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c > index 2294f2061866..5d62abee5262 100644 > --- a/arch/arm64/mm/fault.c > +++ b/arch/arm64/mm/fault.c > @@ -289,9 +289,6 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr, > if (!is_el1_data_abort(esr) || !esr_fsc_is_translation_fault(esr)) > return false; > > - if (is_pkvm_stage2_abort(esr)) > - return false; > - > local_irq_save(flags); > asm volatile("at s1e1r, %0" :: "r" (addr)); > isb(); > @@ -302,8 +299,12 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr, > * If we now have a valid translation, treat the translation fault as > * spurious. > */ > - if (!(par & SYS_PAR_EL1_F)) > + if (!(par & SYS_PAR_EL1_F)) { > + if (is_pkvm_stage2_abort(esr)) > + return pkvm_reclaim_guest_page(par & SYS_PAR_EL1_PA); > + > return true; > + } > > /* > * If we got a different type of fault from the AT instruction, > @@ -389,9 +390,11 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr, > if (!is_el1_instruction_abort(esr) && fixup_exception(regs, esr)) > return; > > - if (WARN_RATELIMIT(is_spurious_el1_translation_fault(addr, esr, regs), > - "Ignoring spurious kernel translation fault at virtual address %016lx\n", addr)) > + if (is_spurious_el1_translation_fault(addr, esr, regs)) { > + WARN_RATELIMIT(!is_pkvm_stage2_abort(esr), > + "Ignoring spurious kernel translation fault at virtual address %016lx\n", addr); > return; > + } > > if (is_el1_mte_sync_tag_check_fault(esr)) { > do_tag_recovery(addr, esr, regs); > -- > 2.52.0.457.g6b5491de43-goog > >