[PATCH 20/20] KVM: arm64: Stage-2 huge mappings for protected VMs

Wei-Lin Chang weilin.chang at arm.com
Mon Sep 7 11:31:17 PDT 2026


On Mon, Aug 03, 2026 at 11:09:04AM +0100, Vincent Donnefort wrote:

[...]

> @@ -1755,25 +1737,59 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
>  		goto unpin;
>  	}
>  
> +	pfn = page_to_pfn(page);
> +	gfn = gpa_to_gfn(s2fd->fault_ipa);
> +
> +	page_size = transparent_hugepage_adjust(kvm, s2fd->memslot, s2fd->hva, &pfn, &gfn);
> +	if (page_size < 0) {
> +		ret = page_size;
> +		goto unpin;
> +	} else if (page_size == PMD_SIZE) {
> +		if (WARN_ON(!folio_test_large(page_folio(page)))) {

folio_size() >= PMD_SIZE seems more robust here.

> +			ret = -EINVAL;
> +			goto unpin;
> +		}
> +	}
> +
> +	ret = account_locked_vm(mm, page_size / PAGE_SIZE, true);

"page_size / PAGE_SIZE" :)
Maybe call this mapping_size?

Thanks,
Wei-Lin Chang

> +	if (ret)
> +		goto unpin;
> +
>  	write_lock(&kvm->mmu_lock);
> -	ret = pkvm_pgtable_stage2_map(pgt, s2fd->fault_ipa, PAGE_SIZE,
> -				      page_to_phys(page), KVM_PGTABLE_PROT_RWX,
> +	ret = pkvm_pgtable_stage2_map(pgt, gfn_to_gpa(gfn), page_size,
> +				      __pfn_to_phys(pfn), KVM_PGTABLE_PROT_RWX,
>  				      hyp_memcache, 0);
>  	write_unlock(&kvm->mmu_lock);
>  	if (ret) {
>  		if (ret == -EAGAIN)
>  			ret = 0;
> -		goto unpin;
> +		goto dec_account;
>  	}
>  
>  	return 0;
> +
> +dec_account:
> +	account_locked_vm(mm, page_size / PAGE_SIZE, false);
>  unpin:
>  	unpin_user_pages(&page, 1);
> -dec_account:
> -	account_locked_vm(mm, 1, false);
>  	return ret;
>  }
>  

[...]



More information about the linux-arm-kernel mailing list