]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
KVM: arm64: Split init and set for table PTE
authorOliver Upton <oliver.upton@linux.dev>
Mon, 7 Nov 2022 21:56:40 +0000 (21:56 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 10 Nov 2022 14:43:46 +0000 (14:43 +0000)
Create a helper to initialize a table and directly call
smp_store_release() to install it (for now). Prepare for a subsequent
change that generalizes PTE writes with a helper.

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-11-oliver.upton@linux.dev
arch/arm64/kvm/hyp/pgtable.c

index a34e2050f9314b05f1faf6b8d03884c219c6e425..f4dd77c6c97d243c3e591c70f04cf8827b373667 100644 (file)
@@ -136,16 +136,13 @@ static void kvm_clear_pte(kvm_pte_t *ptep)
        WRITE_ONCE(*ptep, 0);
 }
 
-static void kvm_set_table_pte(kvm_pte_t *ptep, kvm_pte_t *childp,
-                             struct kvm_pgtable_mm_ops *mm_ops)
+static kvm_pte_t kvm_init_table_pte(kvm_pte_t *childp, struct kvm_pgtable_mm_ops *mm_ops)
 {
-       kvm_pte_t old = *ptep, pte = kvm_phys_to_pte(mm_ops->virt_to_phys(childp));
+       kvm_pte_t pte = kvm_phys_to_pte(mm_ops->virt_to_phys(childp));
 
        pte |= FIELD_PREP(KVM_PTE_TYPE, KVM_PTE_TYPE_TABLE);
        pte |= KVM_PTE_VALID;
-
-       WARN_ON(kvm_pte_valid(old));
-       smp_store_release(ptep, pte);
+       return pte;
 }
 
 static kvm_pte_t kvm_init_valid_leaf_pte(u64 pa, kvm_pte_t attr, u32 level)
@@ -413,7 +410,7 @@ static bool hyp_map_walker_try_leaf(const struct kvm_pgtable_visit_ctx *ctx,
 static int hyp_map_walker(const struct kvm_pgtable_visit_ctx *ctx,
                          enum kvm_pgtable_walk_flags visit)
 {
-       kvm_pte_t *childp;
+       kvm_pte_t *childp, new;
        struct hyp_map_data *data = ctx->arg;
        struct kvm_pgtable_mm_ops *mm_ops = ctx->mm_ops;
 
@@ -427,8 +424,10 @@ static int hyp_map_walker(const struct kvm_pgtable_visit_ctx *ctx,
        if (!childp)
                return -ENOMEM;
 
-       kvm_set_table_pte(ctx->ptep, childp, mm_ops);
+       new = kvm_init_table_pte(childp, mm_ops);
        mm_ops->get_page(ctx->ptep);
+       smp_store_release(ctx->ptep, new);
+
        return 0;
 }
 
@@ -796,7 +795,7 @@ static int stage2_map_walk_leaf(const struct kvm_pgtable_visit_ctx *ctx,
                                struct stage2_map_data *data)
 {
        struct kvm_pgtable_mm_ops *mm_ops = ctx->mm_ops;
-       kvm_pte_t *childp;
+       kvm_pte_t *childp, new;
        int ret;
 
        ret = stage2_map_walker_try_leaf(ctx, data);
@@ -821,8 +820,9 @@ static int stage2_map_walk_leaf(const struct kvm_pgtable_visit_ctx *ctx,
        if (stage2_pte_is_counted(ctx->old))
                stage2_put_pte(ctx, data->mmu, mm_ops);
 
-       kvm_set_table_pte(ctx->ptep, childp, mm_ops);
+       new = kvm_init_table_pte(childp, mm_ops);
        mm_ops->get_page(ctx->ptep);
+       smp_store_release(ctx->ptep, new);
 
        return 0;
 }