[PATCH 1/3] KVM: riscv: Pass the target size to huge G-stage checks
Nutty.Liu
nutty.liu at hotmail.com
Mon Jun 1 01:53:02 PDT 2026
On 5/20/2026 11:21 PM, Jinyu Tang 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 <tjytimi at 163.com>
> ---
> 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;
Seems they are not exactly the same.
Should be like this ?
+ return (hva >= ALIGN(uaddr_start, map_size)) && (hva < ALIGN_DOWN(uaddr_end, map_size));
Otherwise,
Reviewed-by: Nutty Liu <nutty.liu at hotmail.com>
Thanks,
Nutty
> }
>
> 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);
More information about the kvm-riscv
mailing list