Skip to content

Commit 9d8604b

Browse files
author
Marc Zyngier
committed
KVM: arm64: Rework kvm_pgtable initialisation
Ganapatrao reported that the kvm_pgtable->mmu pointer is more or less hardcoded to the main S2 mmu structure, while the nested code needs it to point to other instances (as we have one instance per nested context). Rework the initialisation of the kvm_pgtable structure so that this assumtion doesn't hold true anymore. This requires some minor changes to the order in which things are initialised (the mmu->arch pointer being the critical one). Reported-by: Ganapatrao Kulkarni <[email protected]> Reviewed-by: Ganapatrao Kulkarni <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 142ff9b commit 9d8604b

File tree

4 files changed

+11
-12
lines changed

4 files changed

+11
-12
lines changed

arch/arm64/include/asm/kvm_pgtable.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,22 +270,21 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift);
270270
/**
271271
* __kvm_pgtable_stage2_init() - Initialise a guest stage-2 page-table.
272272
* @pgt: Uninitialised page-table structure to initialise.
273-
* @arch: Arch-specific KVM structure representing the guest virtual
274-
* machine.
273+
* @mmu: S2 MMU context for this S2 translation
275274
* @mm_ops: Memory management callbacks.
276275
* @flags: Stage-2 configuration flags.
277276
* @force_pte_cb: Function that returns true if page level mappings must
278277
* be used instead of block mappings.
279278
*
280279
* Return: 0 on success, negative error code on failure.
281280
*/
282-
int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
281+
int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
283282
struct kvm_pgtable_mm_ops *mm_ops,
284283
enum kvm_pgtable_stage2_flags flags,
285284
kvm_pgtable_force_pte_cb_t force_pte_cb);
286285

287-
#define kvm_pgtable_stage2_init(pgt, arch, mm_ops) \
288-
__kvm_pgtable_stage2_init(pgt, arch, mm_ops, 0, NULL)
286+
#define kvm_pgtable_stage2_init(pgt, mmu, mm_ops) \
287+
__kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL)
289288

290289
/**
291290
* kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,19 @@ int kvm_host_prepare_stage2(void *pgt_pool_base)
103103

104104
prepare_host_vtcr();
105105
hyp_spin_lock_init(&host_kvm.lock);
106+
mmu->arch = &host_kvm.arch;
106107

107108
ret = prepare_s2_pool(pgt_pool_base);
108109
if (ret)
109110
return ret;
110111

111-
ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, &host_kvm.arch,
112+
ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, mmu,
112113
&host_kvm.mm_ops, KVM_HOST_S2_FLAGS,
113114
host_stage2_force_pte_cb);
114115
if (ret)
115116
return ret;
116117

117118
mmu->pgd_phys = __hyp_pa(host_kvm.pgt.pgd);
118-
mmu->arch = &host_kvm.arch;
119119
mmu->pgt = &host_kvm.pgt;
120120
WRITE_ONCE(mmu->vmid.vmid_gen, 0);
121121
WRITE_ONCE(mmu->vmid.vmid, 0);

arch/arm64/kvm/hyp/pgtable.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,13 +1116,13 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
11161116
}
11171117

11181118

1119-
int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
1119+
int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
11201120
struct kvm_pgtable_mm_ops *mm_ops,
11211121
enum kvm_pgtable_stage2_flags flags,
11221122
kvm_pgtable_force_pte_cb_t force_pte_cb)
11231123
{
11241124
size_t pgd_sz;
1125-
u64 vtcr = arch->vtcr;
1125+
u64 vtcr = mmu->arch->vtcr;
11261126
u32 ia_bits = VTCR_EL2_IPA(vtcr);
11271127
u32 sl0 = FIELD_GET(VTCR_EL2_SL0_MASK, vtcr);
11281128
u32 start_level = VTCR_EL2_TGRAN_SL0_BASE - sl0;
@@ -1135,7 +1135,7 @@ int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
11351135
pgt->ia_bits = ia_bits;
11361136
pgt->start_level = start_level;
11371137
pgt->mm_ops = mm_ops;
1138-
pgt->mmu = &arch->mmu;
1138+
pgt->mmu = mmu;
11391139
pgt->flags = flags;
11401140
pgt->force_pte_cb = force_pte_cb;
11411141

arch/arm64/kvm/mmu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
516516
if (!pgt)
517517
return -ENOMEM;
518518

519-
err = kvm_pgtable_stage2_init(pgt, &kvm->arch, &kvm_s2_mm_ops);
519+
mmu->arch = &kvm->arch;
520+
err = kvm_pgtable_stage2_init(pgt, mmu, &kvm_s2_mm_ops);
520521
if (err)
521522
goto out_free_pgtable;
522523

@@ -529,7 +530,6 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
529530
for_each_possible_cpu(cpu)
530531
*per_cpu_ptr(mmu->last_vcpu_ran, cpu) = -1;
531532

532-
mmu->arch = &kvm->arch;
533533
mmu->pgt = pgt;
534534
mmu->pgd_phys = __pa(pgt->pgd);
535535
WRITE_ONCE(mmu->vmid.vmid_gen, 0);

0 commit comments

Comments
 (0)