/* Recreate the hyp page-table using the early page allocator */
hyp_early_alloc_init(hyp_pgt_base, pgt_size);
ret = kvm_pgtable_hyp_init(&pkvm_pgtable, hyp_va_bits,
&hyp_early_alloc_mm_ops); if (ret) return ret;
ret = hyp_create_idmap(hyp_va_bits); if (ret) return ret;
ret = hyp_map_vectors(); if (ret) return ret;
ret = hyp_back_vmemmap(hyp_virt_to_phys(vmemmap_base)); if (ret) return ret;
ret = pkvm_create_mappings(__hyp_text_start, __hyp_text_end, PAGE_HYP_EXEC); if (ret) return ret;
ret = pkvm_create_mappings(__hyp_data_start, __hyp_data_end, PAGE_HYP); if (ret) return ret;
ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO); if (ret) return ret;
ret = pkvm_create_mappings(__hyp_bss_start, __hyp_bss_end, PAGE_HYP); if (ret) return ret;
ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP); if (ret) return ret;
for (i = 0; i < hyp_nr_cpus; i++) { struct kvm_nvhe_init_params *params = per_cpu_ptr(&kvm_init_params, i);
start = (void *)kern_hyp_va(per_cpu_base[i]);
end = start + PAGE_ALIGN(hyp_percpu_size);
ret = pkvm_create_mappings(start, end, PAGE_HYP); if (ret) return ret;
ret = pkvm_create_stack(params->stack_pa, ¶ms->stack_hyp_va); if (ret) return ret;
}
if (ctx->level != KVM_PGTABLE_LAST_LEVEL) return -EINVAL;
phys = kvm_pte_to_phys(ctx->old); if (!addr_is_memory(phys)) return -EINVAL;
page = hyp_phys_to_page(phys);
/* * Adjust the host stage-2 mappings to match the ownership attributes * configured in the hypervisor stage-1, and make sure to propagate them * to the hyp_vmemmap state.
*/
state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(ctx->old)); switch (state) { case PKVM_PAGE_OWNED:
set_hyp_state(page, PKVM_PAGE_OWNED); return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP); case PKVM_PAGE_SHARED_OWNED:
set_hyp_state(page, PKVM_PAGE_SHARED_OWNED);
set_host_state(page, PKVM_PAGE_SHARED_BORROWED); break; case PKVM_PAGE_SHARED_BORROWED:
set_hyp_state(page, PKVM_PAGE_SHARED_BORROWED);
set_host_state(page, PKVM_PAGE_SHARED_OWNED); break; default: return -EINVAL;
}
return 0;
}
staticint fix_hyp_pgtable_refcnt_walker(conststruct kvm_pgtable_visit_ctx *ctx, enum kvm_pgtable_walk_flags visit)
{ /* * Fix-up the refcount for the page-table pages as the early allocator * was unable to access the hyp_vmemmap and so the buddy allocator has * initialised the refcount to '1'.
*/ if (kvm_pte_valid(ctx->old))
ctx->mm_ops->get_page(ctx->ptep);
return 0;
}
staticint fix_host_ownership(void)
{ struct kvm_pgtable_walker walker = {
.cb = fix_host_ownership_walker,
.flags = KVM_PGTABLE_WALK_LEAF,
}; int i, ret;
for (i = 0; i < hyp_memblock_nr; i++) { struct memblock_region *reg = &hyp_memory[i];
u64 start = (u64)hyp_phys_to_virt(reg->base);
ret = kvm_pgtable_walk(&pkvm_pgtable, start, reg->size, &walker); if (ret) return ret;
}
/* Now that the vmemmap is backed, install the full-fledged allocator */
pfn = hyp_virt_to_pfn(hyp_pgt_base);
nr_pages = hyp_s1_pgtable_pages();
reserved_pages = hyp_early_alloc_nr_used_pages();
ret = hyp_pool_init(&hpool, pfn, nr_pages, reserved_pages); if (ret) goto out;
ret = kvm_host_prepare_stage2(host_s2_pgt_base); if (ret) goto out;
ret = fix_hyp_pgtable_refcnt(); if (ret) goto out;
ret = hyp_create_fixmap(); if (ret) goto out;
ret = hyp_ffa_init(ffa_proxy_pages); if (ret) goto out;
pkvm_hyp_vm_table_init(vm_table_base);
pkvm_ownership_selftest(selftest_base);
out: /* * We tail-called to here from handle___pkvm_init() and will not return, * so make sure to propagate the return value to the host.
*/
cpu_reg(host_ctxt, 1) = ret;
ret = divide_memory_pool(virt, size); if (ret) return ret;
ret = recreate_hyp_mappings(phys, size, per_cpu_base, hyp_va_bits); if (ret) return ret;
update_nvhe_init_params();
/* Jump in the idmap page to switch to the new page-tables */
params = this_cpu_ptr(&kvm_init_params);
fn = (typeof(fn))__hyp_pa(__pkvm_init_switch_pgd);
fn(params->pgd_pa, params->stack_hyp_va, __pkvm_init_finalise);
unreachable();
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.