Skip to content

Commit d6b4bd3

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Fixup hyp stage-1 refcount
In nVHE-protected mode, the hyp stage-1 page-table refcount is broken due to the lack of refcount support in the early allocator. Fix-up the refcount in the finalize walker, once the 'hyp_vmemmap' is up and running. Acked-by: Will Deacon <[email protected]> Signed-off-by: Quentin Perret <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2ea2ff9 commit d6b4bd3

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

arch/arm64/kvm/hyp/nvhe/setup.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
165165
enum kvm_pgtable_walk_flags flag,
166166
void * const arg)
167167
{
168+
struct kvm_pgtable_mm_ops *mm_ops = arg;
168169
enum kvm_pgtable_prot prot;
169170
enum pkvm_page_state state;
170171
kvm_pte_t pte = *ptep;
@@ -173,6 +174,15 @@ static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
173174
if (!kvm_pte_valid(pte))
174175
return 0;
175176

177+
/*
178+
* Fix-up the refcount for the page-table pages as the early allocator
179+
* was unable to access the hyp_vmemmap and so the buddy allocator has
180+
* initialised the refcount to '1'.
181+
*/
182+
mm_ops->get_page(ptep);
183+
if (flag != KVM_PGTABLE_WALK_LEAF)
184+
return 0;
185+
176186
if (level != (KVM_PGTABLE_MAX_LEVELS - 1))
177187
return -EINVAL;
178188

@@ -205,7 +215,8 @@ static int finalize_host_mappings(void)
205215
{
206216
struct kvm_pgtable_walker walker = {
207217
.cb = finalize_host_mappings_walker,
208-
.flags = KVM_PGTABLE_WALK_LEAF,
218+
.flags = KVM_PGTABLE_WALK_LEAF | KVM_PGTABLE_WALK_TABLE_POST,
219+
.arg = pkvm_pgtable.mm_ops,
209220
};
210221
int i, ret;
211222

@@ -240,10 +251,6 @@ void __noreturn __pkvm_init_finalise(void)
240251
if (ret)
241252
goto out;
242253

243-
ret = finalize_host_mappings();
244-
if (ret)
245-
goto out;
246-
247254
pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) {
248255
.zalloc_page = hyp_zalloc_hyp_page,
249256
.phys_to_virt = hyp_phys_to_virt,
@@ -253,6 +260,10 @@ void __noreturn __pkvm_init_finalise(void)
253260
};
254261
pkvm_pgtable.mm_ops = &pkvm_pgtable_mm_ops;
255262

263+
ret = finalize_host_mappings();
264+
if (ret)
265+
goto out;
266+
256267
out:
257268
/*
258269
* We tail-called to here from handle___pkvm_init() and will not return,

0 commit comments

Comments
 (0)