From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9394924677B for ; Thu, 28 May 2026 22:36:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780007770; cv=none; b=Kl1W1es7OWBoWGAOYM5MBoyQRpuCAIN/9HLVO/aElv0mZoAraDmUwgq8LapLZATclTZki8R28eD/P1OO1wYB4y9Ilx+kx+df8Vnv1yA3b2cwxfMa08IelnLYw1fzrkB7pyNbgIUs+cGikVz3Fu/vjoTuInQf5364HBqdAIYBiw0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780007770; c=relaxed/simple; bh=f3V1T213crjqEMKsLX47h1szEUJL4Peo5rHdM1x7d2w=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=XCbK4FIO1JeabgEl8WsqhaD/ALt5qgtx+8Mb6B7x+dXES4Ubtgkkodco0aP0a4IcbumrG5FDCN2DH2WvjttzeaXLq4l8rS+EIOszTv5XOiojp86EnFjn+IIbT9BH7QDSIFYjlwJznDUdMpU6N83XdOCzFAidKLlZ7ff8IGg4Uc0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RSOTnADR; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RSOTnADR" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-2bc85eda6b6so67643515ad.1 for ; Thu, 28 May 2026 15:36:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780007767; x=1780612567; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=j6G7TGbV2srXAXSbKsGpAGcrEaEACN1hpS7t4zOGNfc=; b=RSOTnADRkUY1MHlROqnKtGm2+cfL1lQclFmfjbDnOgnKp+1mmqP2rBcBc3KZl8LBAC F2f7vh9jCtsHxdghTdfHfdGOj7K6n7EfYpJ8QyopJuTR5TvQ6ysQFAjYchVEJ6AH1RsO 7ZKHdpcDEJ7gQO9j9EfCvjg8/BTVUOE+yI6WixoDdwGa0j+IlZKRVD4hZbLYf9c3K6WF TgxW2+CDvFDt6LN7AfBQ9cItK60lUlxEq1Dk11ZPQbj3oeJPDlFnoh/UkFapR1mzYSxJ 83h6Zh4W6m9kE+xvqEfgNRw0IYVjUvPlQLPg6ODd4Qithb/fvhfT7y9DDrMRWdxP1dmS dmQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780007767; x=1780612567; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=j6G7TGbV2srXAXSbKsGpAGcrEaEACN1hpS7t4zOGNfc=; b=ej3kuVVe8dO2+zC6rMwK4Oc+MKQTC/qIzSbKH7jI/vXDkV+Wq+/km8vBSV//oHPS9v dVmXbUCdsjTYOtIlOt58UvKyT41gPRrJCWKIVV+NYsinNDZ01v7SkPnU7Q+nnrR61zrU VxT44BNiA+JTx0pBY5z7NYzM+nPkP391eUo9ITg5kZvGKUuLxsI76H68nmwrfsSvSidC NOOEHxfpOrIL5LCM5DBxcLUQRmbhB19pv7ZFGOSRPaThYeU9cZMm2AxgJmvBKCjS7Eud M0k5T8b1yo4/VXtBALExmGk2DFGZZv7ORptxBCkJCMQx/OPMbzD/avwsH6WA/8vWUFGX ZNYg== X-Forwarded-Encrypted: i=1; AFNElJ8NUto12lTjnWliRkXy4W6peVjb+X5DliEbQBzArzmK23ljpNgqs87wZMdWWMjGsUKWprfxtPo+WLUe9bM=@vger.kernel.org X-Gm-Message-State: AOJu0YxdTC7AzfWGrfvDmXYAG3RIjjYzNLoToPjlBqUeMyo5U1Trcfnx F/gAcOHWaIIlPkPWkeiWRpjAnl/VirUiTREdS7ueDwYxUVUumKmEnxyO X-Gm-Gg: Acq92OFTX1DLpVsyGLgCzYzTA25CJHNs2OkqUv2DUxN48kDXXYYsHzxsHJyY82pF1Il JfyuR/MTS1URdm9EHsZXSbBGbGAHR4gC1zAjmE5idF3IX6IRyOw6qNm3/13pRyP3CkiajFM4VdP NxNsmZTlaj6r5NDBq90EYfw836mN0ViXRbfjL0YGWUgwShHZQTIINkBVXAAQu00CgOual1kXtnT OqU91uwqhs1DGYzpR53xCSLiIbBIzt93CJKeg5+N6UXjZjg+nBkQk4NIekbe6sg/VBY3WOO2pGh Q+k/st4TdLUaIcsM4Vzsg4ugSizGLJto9O2mMYHBOq10PIqwEnyR66GAU1crrk4VGwgeHNfkg5C iEjVnv0M9S9MXK6T6qzXb1NXNBc6lb4UC8F1qwMF9qMbKPfCi6kayEzPY7FHB1tQjh7Ly/7rb63 tvXAoHMFRCD6Pr5XBcQnrKcbHIADZEfFNbUw== X-Received: by 2002:a17:902:fc8f:b0:2b9:ec37:2977 with SMTP id d9443c01a7336-2bf20cf15a1mr3611585ad.38.1780007766821; Thu, 28 May 2026 15:36:06 -0700 (PDT) Received: from localhost ([2001:19f0:8001:1b2d:5400:5ff:fefa:a95d]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2bf218a2535sm855155ad.29.2026.05.28.15.36.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 May 2026 15:36:05 -0700 (PDT) Date: Fri, 29 May 2026 06:35:54 +0800 From: Inochi Amaoto To: Jinyu Tang , 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, Atish Patra , Paul Walmsley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Radim =?utf-8?B?S3LEjW3DocWZ?= , Andrew Jones , Conor Dooley , Yong-Xuan Wang , Nutty Liu Subject: Re: [PATCH 5/5] KVM: riscv: Fast-path dirty logging write faults Message-ID: References: <20260517153427.94889-1-tjytimi@163.com> <20260517153427.94889-6-tjytimi@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260517153427.94889-6-tjytimi@163.com> On Sun, May 17, 2026 at 11:34:27PM +0800, Jinyu Tang wrote: > With dirty logging enabled, guest writes often fault on an existing 4K > G-stage leaf that was write-protected only for dirty tracking. The slow > path still performs the full fault handling flow and takes mmu_lock for > write, even though the page-table shape does not change. > > x86 handles the analogous case in its fast page fault path by atomically > making a writable SPTE writable again when the fault is only a > write-protection fault. Add the same style of fast path for RISC-V. If a > write fault hits an existing 4K leaf in a writable dirty-log memslot, > mark the page dirty and atomically set the PTE writable and dirty under > the read side of mmu_lock. > > The dirty bitmap is updated before the PTE becomes writable again. The > PTE D bit is also set so systems that trap on a clear D bit do not fall > back to the slow path for a writable but clean PTE. > > Signed-off-by: Jinyu Tang > --- > arch/riscv/kvm/mmu.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 75 insertions(+) > > diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c > index 48f16e52f..980059e09 100644 > --- a/arch/riscv/kvm/mmu.c > +++ b/arch/riscv/kvm/mmu.c > @@ -419,6 +419,77 @@ static unsigned long transparent_hugepage_adjust(struct kvm *kvm, > return PAGE_SIZE; > } > > +static bool kvm_riscv_mmu_dirty_log_write_fault_fast(struct kvm *kvm, > + struct kvm_memory_slot *memslot, > + gpa_t gpa, > + struct kvm_gstage_mapping *out_map) > +{ > + struct kvm_gstage gstage; > + unsigned long mmu_seq; > + pte_t old_pte, new_pte; > + pte_t *ptep; > + gfn_t gfn = gpa >> PAGE_SHIFT; > + u32 ptep_level; > + bool dirty_marked = false; > + bool ret; > + > + kvm_riscv_gstage_init(&gstage, kvm); > + mmu_seq = kvm->mmu_invalidate_seq; > + > + read_lock(&kvm->mmu_lock); > + > + if (mmu_invalidate_retry_gfn(kvm, mmu_seq, gfn)) { > + ret = false; > + goto out_unlock; > + } > + > + if (!kvm_riscv_gstage_get_leaf(&gstage, gpa, &ptep, &ptep_level) || > + ptep_level) { > + ret = false; > + goto out_unlock; > + } > + Add a check here: if this is a huge page and is a logging page, we should fallback to slow path to apply page spltting. > + for (;;) { > + old_pte = ptep_get(ptep); > + if (!(pte_val(old_pte) & _PAGE_LEAF)) { Use pmd_present() here. > + ret = false; > + break; > + } > + > + if (!dirty_marked) { > + mark_page_dirty_in_slot(kvm, memslot, gfn); > + dirty_marked = true; > + } Only log dirty entry when the updating is success, otherwise the page could be record twice in both fast and slow path. > + > + if ((pte_val(old_pte) & (_PAGE_WRITE | _PAGE_DIRTY)) == > + (_PAGE_WRITE | _PAGE_DIRTY)) { I think only pte_write is required, for write-protected path, only write permission is needed to be checked, as we always set dirty bit. For the future dirty log hardware extension, the Svadu will update the dirty bit so no need for this logic. > + new_pte = old_pte; > + ret = true; > + break; > + } > + > + new_pte = pte_mkdirty(pte_mkwrite_novma(old_pte)); pte_mkyoung is also needed. > + > + if (kvm_riscv_gstage_try_update_pte(&gstage, ptep_level, gpa, > + ptep, old_pte, new_pte)) { > + ret = true; > + break; > + } > + cpu_relax(); > + } > + > +out_unlock: > + read_unlock(&kvm->mmu_lock); > + > + if (ret) { > + out_map->addr = gpa & PAGE_MASK; > + out_map->level = 0; > + out_map->pte = new_pte; > + } > + > + return ret; > +} > + > int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, > gpa_t gpa, unsigned long hva, bool is_write, > struct kvm_gstage_mapping *out_map) > @@ -442,6 +513,10 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, > /* Setup initial state of output mapping */ > memset(out_map, 0, sizeof(*out_map)); > > + if (is_write && logging && > + kvm_riscv_mmu_dirty_log_write_fault_fast(kvm, memslot, gpa, out_map)) > + return 0; > + > /* We need minimum second+third level pages */ > ret = kvm_mmu_topup_memory_cache(pcache, kvm->arch.pgd_levels); > if (ret) { > -- > 2.43.0 > Regards, Inochi