diff options
author | Oliver Upton <oliver.upton@linux.dev> | 2022-11-07 21:56:35 +0000 |
---|---|---|
committer | Marc Zyngier <maz@kernel.org> | 2022-11-10 14:43:46 +0000 |
commit | 8e94e1252cc054bb31fd3e9a15235cd831970ec1 (patch) | |
tree | 6c014757ce57ce0ff55786d83d8820388d15be4f /arch/arm64/kvm/hyp | |
parent | fa002e8e79b3f980455ba585c1f47b26680de5b9 (diff) | |
download | linux-stable-8e94e1252cc054bb31fd3e9a15235cd831970ec1.tar.gz linux-stable-8e94e1252cc054bb31fd3e9a15235cd831970ec1.tar.bz2 linux-stable-8e94e1252cc054bb31fd3e9a15235cd831970ec1.zip |
KVM: arm64: Add a helper to tear down unlinked stage-2 subtrees
A subsequent change to KVM will move the tear down of an unlinked
stage-2 subtree out of the critical path of the break-before-make
sequence.
Introduce a new helper for tearing down unlinked stage-2 subtrees.
Leverage the existing stage-2 free walkers to do so, with a deep call
into __kvm_pgtable_walk() as the subtree is no longer reachable from the
root.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20221107215644.1895162-6-oliver.upton@linux.dev
Diffstat (limited to 'arch/arm64/kvm/hyp')
-rw-r--r-- | arch/arm64/kvm/hyp/pgtable.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 93989b750a26..363a5cce7e1a 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -1203,3 +1203,26 @@ void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) pgt->mm_ops->free_pages_exact(pgt->pgd, pgd_sz); pgt->pgd = NULL; } + +void kvm_pgtable_stage2_free_removed(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, u32 level) +{ + kvm_pte_t *ptep = (kvm_pte_t *)pgtable; + struct kvm_pgtable_walker walker = { + .cb = stage2_free_walker, + .flags = KVM_PGTABLE_WALK_LEAF | + KVM_PGTABLE_WALK_TABLE_POST, + }; + struct kvm_pgtable_walk_data data = { + .walker = &walker, + + /* + * At this point the IPA really doesn't matter, as the page + * table being traversed has already been removed from the stage + * 2. Set an appropriate range to cover the entire page table. + */ + .addr = 0, + .end = kvm_granule_size(level), + }; + + WARN_ON(__kvm_pgtable_walk(&data, mm_ops, ptep, level)); +} |