Re: [PATCH 1/3] KVM: riscv: Pass the target size to huge G-stage checks
Anup Patel <[email protected]>
| Newsgroups | org.infradead.lists.kvm-riscv,org.infradead.lists.linux-riscv,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAAhSdy14_aMXR6ztaQySOxQqaUNTARfhuZd=pTS=52nXrTQrEw@mail.gmail.com> |
On Wed, May 20, 2026 at 8:52 PM Jinyu Tang <[email protected]> wrote: > > fault_supports_gstage_huge_mapping() already contains the two checks > needed before installing a G-stage block mapping: the userspace address > and GPA must have matching offsets within the block, and the whole block > must be contained within the memslot. > > The helper currently hard-codes PMD_SIZE because its only caller is the > transparent hugepage path. The hugetlb path needs the same checks, but > the target block size can be either PMD_SIZE or PUD_SIZE depending on the > hugetlb VMA. > > So pass the target mapping size into the helper and use it for the > alignment and bounds checks. This keeps the existing THP PMD behavior > unchanged and prepares the helper to be reused for the following hugetlb > fix. > > Signed-off-by: Jinyu Tang <[email protected]> > --- > arch/riscv/kvm/mmu.c | 14 ++++++++------ > 1 file changed, 8 insertions(+), 6 deletions(-) > > diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c > index 2d3def024..10be8f683 100644 > --- a/arch/riscv/kvm/mmu.c > +++ b/arch/riscv/kvm/mmu.c > @@ -286,7 +286,8 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) > } > > static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot, > - unsigned long hva) > + unsigned long hva, > + unsigned long map_size) > { > hva_t uaddr_start, uaddr_end; > gpa_t gpa_start; > @@ -300,8 +301,8 @@ static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot, > > /* > * Pages belonging to memslots that don't have the same alignment > - * within a PMD for userspace and GPA cannot be mapped with g-stage > - * PMD entries, because we'll end up mapping the wrong pages. > + * within a huge page for userspace and GPA cannot be mapped with > + * g-stage block entries, because we'll end up mapping the wrong pages. > * > * Consider a layout like the following: > * > @@ -321,7 +322,7 @@ static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot, > * e -> g > * f -> h > */ > - if ((gpa_start & (PMD_SIZE - 1)) != (uaddr_start & (PMD_SIZE - 1))) > + if ((gpa_start & (map_size - 1)) != (uaddr_start & (map_size - 1))) > return false; > > /* > @@ -336,7 +337,8 @@ static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot, > * userspace_addr or the base_gfn, as both are equally aligned (per > * the check above) and equally sized. > */ > - return (hva >= ALIGN(uaddr_start, PMD_SIZE)) && (hva < ALIGN_DOWN(uaddr_end, PMD_SIZE)); > + return (hva & ~(map_size - 1)) >= uaddr_start && > + (hva & ~(map_size - 1)) + map_size <= uaddr_end; This looks counter intuitive. Why not have "(hva >= ALIGN(uaddr_start, map_size)) && (hva < ALIGN_DOWN(uaddr_end, map_size))" ? > } > > static int get_hva_mapping_size(struct kvm *kvm, > @@ -404,7 +406,7 @@ static unsigned long transparent_hugepage_adjust(struct kvm *kvm, > * sure that the HVA and GPA are sufficiently aligned and that the > * block map is contained within the memslot. > */ > - if (fault_supports_gstage_huge_mapping(memslot, hva)) { > + if (fault_supports_gstage_huge_mapping(memslot, hva, PMD_SIZE)) { > int sz; > > sz = get_hva_mapping_size(kvm, hva); > -- > 2.43.0 > Regards, Anup -- kvm-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kvm-riscv