diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index 569f3be83a17..c0f502c5edb2 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -277,6 +277,29 @@ static int fix_hyp_pgtable_refcnt_walker(u64 addr, u64 end, u32 level, return 0; } +static int pin_table_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, + enum kvm_pgtable_walk_flags flag, void * const arg) +{ + struct kvm_pgtable_mm_ops *mm_ops = arg; + kvm_pte_t pte = *ptep; + + if (kvm_pte_valid(pte)) + mm_ops->get_page(kvm_pte_follow(pte, mm_ops)); + + return 0; +} + +static int pin_host_tables(void) +{ + struct kvm_pgtable_walker walker = { + .cb = pin_table_walker, + .flags = KVM_PGTABLE_WALK_TABLE_POST, + .arg = &host_mmu.mm_ops, + }; + + return kvm_pgtable_walk(&host_mmu.pgt, 0, BIT(host_mmu.pgt.ia_bits), &walker); +} + static int fix_host_ownership(void) { struct kvm_pgtable_walker walker = { @@ -373,6 +396,10 @@ void __noreturn __pkvm_init_finalise(void) if (ret) goto out; + ret = pin_host_tables(); + if (ret) + goto out; + ret = hyp_ffa_init(ffa_proxy_pages); if (ret) goto out;