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 7335CC5CFE7 for ; Tue, 11 Aug 2026 23:03:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=NBvbfHQ25IsPQ9gESOn5m92ge7oBsMyWxSGu64r/Tjg=; b=IASqj/3nCArd3Y NFu3jZumTBdh2GS8bNGLHKPtdXpqYTpoxbb0GHuHxoFnU4W8B+TP/f7OoWwuTskQGzR24tX3pPqjy E798dInSfQDOkUvN/MdgUpnDGB88Cf1ybZAMdAlWWkj94KIjde90XY6CHV2NpaxRw8fTNjWDL/kvk 3mt7d7Xx3j1o08/m/t7R4ZGGGzv4Gu0Jov+ERqcV53LnAhgf0S7CcaxGnsFImjRFiUwBpBX4BJMkK qd0Fv3KWLR/LMbQTXyM6M2k+G2U19fA8C2D36hRyhOuCyCVkViXD14J8rvVQxI5FZaq60wJ/7S0vR ivBu78c+ZG658e9V1NAQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wtvVX-0000000F3df-0XQn; Tue, 11 Aug 2026 23:03:43 +0000 Received: from out-174.mta0.migadu.com ([2001:41d0:1004:224b::ae]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wtvVU-0000000F3c4-2MO4 for kvm-riscv@lists.infradead.org; Tue, 11 Aug 2026 23:03:41 +0000 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1786489417; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OUZulxlEFenT7RvZakt+p4GE/qxIk5ggsq3u1CDIY8o=; b=aKmFALIBIEB1UhNbRDH6xre7z0bcw6q8Ll+3mDGOOS2KPmUD8CLCAFcA8G3EXol/OGGNDu wlpUfjHFYoTy5Gj4sA4rxm5R4E6VWWtdUuFRsJMQwHircRbYKaIXL4SQtGnM1/Roc4E7DK V0Hg1NBCvboosZvc0nzGC6JqeJ6Y3go= From: Jinyu Tang To: Anup Patel , Anup Patel , Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Atish Patra , Paul Walmsley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Andrew Jones , Conor Dooley , Yong-Xuan Wang , Nutty Liu , Jinyu Tang , Jinyu Tang Subject: [PATCH v2 1/3] KVM: riscv: Implement KVM_PRE_FAULT_MEMORY Date: Wed, 12 Aug 2026 07:03:14 +0800 Message-ID: <20260811230316.218770-2-jinyu.tang@linux.dev> In-Reply-To: <20260811230316.218770-1-jinyu.tang@linux.dev> References: <20260811230316.218770-1-jinyu.tang@linux.dev> MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260811_160340_731529_732BC765 X-CRM114-Status: GOOD ( 12.39 ) X-BeenThere: kvm-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "kvm-riscv" Errors-To: kvm-riscv-bounces+kvm-riscv=archiver.kernel.org@lists.infradead.org The generic KVM_PRE_FAULT_MEMORY ioctl lets userspace populate KVM page tables before running a vCPU over a GPA range. x86 already supports the ioctl, but RISC-V does not expose the capability and has no arch hook. Add the RISC-V arch hook and reuse the existing G-stage fault mapping path with a read access. Report progress using the G-stage mapping returned by the map path, so the ioctl can advance by the actual leaf size that covers the requested GPA. Unlike x86, RISC-V's G-stage fault path does not return a detailed result such as RET_PF_FIXED or RET_PF_RETRY. Treat a successful call that does not return a visible G-stage mapping as no progress, instead of reporting that a page was prefaulted. Signed-off-by: Jinyu Tang --- arch/riscv/kvm/Kconfig | 1 + arch/riscv/kvm/gstage.c | 3 +++ arch/riscv/kvm/mmu.c | 33 +++++++++++++++++++++++++++++++++ arch/riscv/kvm/vm.c | 1 + 4 files changed, 38 insertions(+) diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig index ec2cee0a39e0..8ac209e8ac87 100644 --- a/arch/riscv/kvm/Kconfig +++ b/arch/riscv/kvm/Kconfig @@ -28,6 +28,7 @@ config KVM select KVM_COMMON select KVM_GENERIC_DIRTYLOG_READ_PROTECT select KVM_GENERIC_HARDWARE_ENABLING + select KVM_GENERIC_PRE_FAULT_MEMORY select KVM_MMIO select VIRT_XFER_TO_GUEST_WORK select SCHED_INFO diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c index e5002cb9cbef..6bd8b8fd6ceb 100644 --- a/arch/riscv/kvm/gstage.c +++ b/arch/riscv/kvm/gstage.c @@ -280,6 +280,9 @@ int kvm_riscv_gstage_map_page(struct kvm_gstage *gstage, out_map->level, true); } else if (ALIGN_DOWN(PFN_PHYS(pte_pfn(ptep_get(ptep))), page_size) == hpa) { kvm_riscv_gstage_update_pte_prot(gstage, ptep_level, gpa, ptep, prot); + out_map->addr = ALIGN_DOWN(gpa, page_size); + out_map->level = ptep_level; + out_map->pte = ptep_get(ptep); return 0; } } diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c index 6035b5ec9503..c96e21740c91 100644 --- a/arch/riscv/kvm/mmu.c +++ b/arch/riscv/kvm/mmu.c @@ -748,6 +748,39 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, return ret; } +long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, + struct kvm_pre_fault_memory *range) +{ + struct kvm_gstage_mapping out_map = { 0 }; + struct kvm_memory_slot *memslot; + unsigned long map_size; + unsigned long hva; + gpa_t end; + gfn_t gfn; + int ret; + + gfn = gpa_to_gfn(range->gpa); + memslot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); + if (!memslot) + return -ENOENT; + + hva = gfn_to_hva_memslot_prot(memslot, gfn, NULL); + if (kvm_is_error_hva(hva)) + return -ENOENT; + + ret = kvm_riscv_mmu_map(vcpu, memslot, range->gpa, hva, false, &out_map); + if (ret) + return ret; + + if (!pte_val(out_map.pte)) + return -EAGAIN; + + map_size = PAGE_SIZE << (out_map.level * kvm_riscv_gstage_index_bits); + end = ALIGN_DOWN(range->gpa, map_size) + map_size; + + return min_t(u64, range->size, end - range->gpa); +} + int kvm_riscv_mmu_alloc_pgd(struct kvm *kvm) { struct page *pgd_page; diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c index a9f083feeb76..58500a19b33b 100644 --- a/arch/riscv/kvm/vm.c +++ b/arch/riscv/kvm/vm.c @@ -187,6 +187,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_MP_STATE: case KVM_CAP_IMMEDIATE_EXIT: case KVM_CAP_SET_GUEST_DEBUG: + case KVM_CAP_PRE_FAULT_MEMORY: r = 1; break; case KVM_CAP_NR_VCPUS: -- 2.43.0 -- kvm-riscv mailing list kvm-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kvm-riscv