| Message ID | 20260316141631543e3oVI3JGADhz5veSRD_eC@zte.com.cn |
|---|---|
| State | Changes Requested |
| Headers | show |
| Series | RISC-V: KVM: Fix hugepage mapping handling during dirty logging | expand |
On Mon, Mar 16, 2026 at 11:46 AM <wang.yechao255@zte.com.cn> wrote: > > From: Wang Yechao <wang.yechao255@zte.com.cn> > > When enabling dirty log in small chunks (e.g., QEMU default chunk > size of 256K), the chunk size is always smaller than the page size > of huge pages (1G or 2M) used in the gstage page tables. This caused > the write protection to be incorrectly skipped for huge PTEs because > the condition `(end - addr) >= page_size` was not satisfied. > > Remove the size check in `kvm_riscv_gstage_wp_range()` to ensure huge > PTEs are always write-protected regardless of the chunk size. Additionally, > explicitly align the address down to the page size before invoking > `kvm_riscv_gstage_op_pte()` to guarantee that the address passed to the > operation function is page-aligned. > > This fixes the issue where dirty pages might not be tracked correctly > when using huge pages. > > Fixes: 9d05c1fee837 ("RISC-V: KVM: Implement stage2 page table programming") > Signed-off-by: Wang Yechao <wang.yechao255@zte.com.cn> > Reviewed-by: Nutty Liu <nutty.liu@hotmail.com> LGTM. Reviewed-by: Anup Patel <anup@brainfault.org> Regards, Anup > --- > arch/riscv/kvm/gstage.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c > index b67d60d722c2..d2001d508046 100644 > --- a/arch/riscv/kvm/gstage.c > +++ b/arch/riscv/kvm/gstage.c > @@ -304,10 +304,9 @@ void kvm_riscv_gstage_wp_range(struct kvm_gstage *gstage, gpa_t start, gpa_t end > if (!found_leaf) > goto next; > > - if (!(addr & (page_size - 1)) && ((end - addr) >= page_size)) > - kvm_riscv_gstage_op_pte(gstage, addr, ptep, > - ptep_level, GSTAGE_OP_WP); > - > + addr = ALIGN_DOWN(addr, page_size); > + kvm_riscv_gstage_op_pte(gstage, addr, ptep, > + ptep_level, GSTAGE_OP_WP); > next: > addr += page_size; > } > -- > 2.27.0
diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c index b67d60d722c2..d2001d508046 100644 --- a/arch/riscv/kvm/gstage.c +++ b/arch/riscv/kvm/gstage.c @@ -304,10 +304,9 @@ void kvm_riscv_gstage_wp_range(struct kvm_gstage *gstage, gpa_t start, gpa_t end if (!found_leaf) goto next; - if (!(addr & (page_size - 1)) && ((end - addr) >= page_size)) - kvm_riscv_gstage_op_pte(gstage, addr, ptep, - ptep_level, GSTAGE_OP_WP); - + addr = ALIGN_DOWN(addr, page_size); + kvm_riscv_gstage_op_pte(gstage, addr, ptep, + ptep_level, GSTAGE_OP_WP); next: addr += page_size; }