From: Marc Zyngier <maz@kernel.org>
To: Ricardo Koller <ricarkol@google.com>
Cc: pbonzini@redhat.com, oupton@google.com, yuzenghui@huawei.com,
dmatlack@google.com, kvm@vger.kernel.org, kvmarm@lists.linux.dev,
qperret@google.com, catalin.marinas@arm.com,
andrew.jones@linux.dev, seanjc@google.com,
alexandru.elisei@arm.com, suzuki.poulose@arm.com,
eric.auger@redhat.com, gshan@redhat.com, reijiw@google.com,
rananta@google.com, bgardon@google.com, ricarkol@gmail.com,
Shaoqin Huang <shahuang@redhat.com>
Subject: Re: [PATCH v6 03/12] KVM: arm64: Add helper for creating unlinked stage2 subtrees
Date: Sun, 12 Mar 2023 11:06:31 +0000 [thread overview]
Message-ID: <87bkky5ivc.wl-maz@kernel.org> (raw)
In-Reply-To: <20230307034555.39733-4-ricarkol@google.com>
On Tue, 07 Mar 2023 03:45:46 +0000,
Ricardo Koller <ricarkol@google.com> wrote:
>
> Add a stage2 helper, kvm_pgtable_stage2_create_unlinked(), for
> creating unlinked tables (which is the opposite of
> kvm_pgtable_stage2_free_unlinked()). Creating an unlinked table is
> useful for splitting PMD and PUD blocks into subtrees of PAGE_SIZE
Please drop the PMD/PUD verbiage. That's specially confusing when
everything is described in terms of 'level'
> PTEs. For example, a PUD can be split into PAGE_SIZE PTEs by first
for example: s/a PUD/a level 1 mapping/
> creating a fully populated tree, and then use it to replace the PUD in
> a single step. This will be used in a subsequent commit for eager
> huge-page splitting (a dirty-logging optimization).
>
> No functional change intended. This new function will be used in a
> subsequent commit.
Drop this last sentence, it doesn't say anything that you haven't
already said.
>
> Signed-off-by: Ricardo Koller <ricarkol@google.com>
> Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> arch/arm64/include/asm/kvm_pgtable.h | 28 +++++++++++++++++
> arch/arm64/kvm/hyp/pgtable.c | 46 ++++++++++++++++++++++++++++
> 2 files changed, 74 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index c7a269cad053..b7b3fc0fa7a5 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -468,6 +468,34 @@ void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
> */
> void kvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, u32 level);
>
> +/**
> + * kvm_pgtable_stage2_create_unlinked() - Create an unlinked stage-2 paging structure.
> + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
> + * @phys: Physical address of the memory to map.
> + * @level: Starting level of the stage-2 paging structure to be created.
> + * @prot: Permissions and attributes for the mapping.
> + * @mc: Cache of pre-allocated and zeroed memory from which to allocate
> + * page-table pages.
> + * @force_pte: Force mappings to PAGE_SIZE granularity.
> + *
> + * Returns an unlinked page-table tree. If @force_pte is true or
> + * @level is 2 (the PMD level), then the tree is mapped up to the
> + * PAGE_SIZE leaf PTE; the tree is mapped up one level otherwise.
I wouldn't make this "one level" assumption, as this really depends on
the size of what gets mapped (and future evolution of this code).
> + * This new page-table tree is not reachable (i.e., it is unlinked)
> + * from the root pgd and it's therefore unreachableby the hardware
> + * page-table walker. No TLB invalidation or CMOs are performed.
> + *
> + * If device attributes are not explicitly requested in @prot, then the
> + * mapping will be normal, cacheable.
> + *
> + * Return: The fully populated (unlinked) stage-2 paging structure, or
> + * an ERR_PTR(error) on failure.
What guarantees that this new unlinked structure is kept in sync with
the original one? AFAICT, nothing does.
> + */
> +kvm_pte_t *kvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt,
> + u64 phys, u32 level,
> + enum kvm_pgtable_prot prot,
> + void *mc, bool force_pte);
> +
> /**
> * kvm_pgtable_stage2_map() - Install a mapping in a guest stage-2 page-table.
> * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 4f703cc4cb03..6bdfcb671b32 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -1212,6 +1212,52 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
> return kvm_pgtable_walk(pgt, addr, size, &walker);
> }
>
> +kvm_pte_t *kvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt,
> + u64 phys, u32 level,
> + enum kvm_pgtable_prot prot,
> + void *mc, bool force_pte)
> +{
> + struct stage2_map_data map_data = {
> + .phys = phys,
> + .mmu = pgt->mmu,
> + .memcache = mc,
> + .force_pte = force_pte,
> + };
> + struct kvm_pgtable_walker walker = {
> + .cb = stage2_map_walker,
> + .flags = KVM_PGTABLE_WALK_LEAF |
> + KVM_PGTABLE_WALK_SKIP_BBM |
> + KVM_PGTABLE_WALK_SKIP_CMO,
> + .arg = &map_data,
> + };
> + /* .addr (the IPA) is irrelevant for an unlinked table */
> + struct kvm_pgtable_walk_data data = {
> + .walker = &walker,
> + .addr = 0,
Is that always true? What if the caller expect a non-block-aligned
mapping? You should at least check that phys is aligned to the granule
size of 'level', or bad stuff may happen.
> + .end = kvm_granule_size(level),
> + };
> + struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops;
> + kvm_pte_t *pgtable;
> + int ret;
> +
> + ret = stage2_set_prot_attr(pgt, prot, &map_data.attr);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + pgtable = mm_ops->zalloc_page(mc);
> + if (!pgtable)
> + return ERR_PTR(-ENOMEM);
> +
> + ret = __kvm_pgtable_walk(&data, mm_ops, (kvm_pteref_t)pgtable,
> + level + 1);
> + if (ret) {
> + kvm_pgtable_stage2_free_unlinked(mm_ops, pgtable, level);
> + mm_ops->put_page(pgtable);
> + return ERR_PTR(ret);
> + }
> +
> + return pgtable;
> +}
>
> int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
> struct kvm_pgtable_mm_ops *mm_ops,
M.
--
Without deviation from the norm, progress is not possible.
next prev parent reply other threads:[~2023-03-12 11:06 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-07 3:45 [PATCH v6 00/12] Implement Eager Page Splitting for ARM Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 01/12] KVM: arm64: Rename free_removed to free_unlinked Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 02/12] KVM: arm64: Add KVM_PGTABLE_WALK ctx->flags for skipping BBM and CMO Ricardo Koller
2023-03-12 10:49 ` Marc Zyngier
2023-03-13 18:49 ` Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 03/12] KVM: arm64: Add helper for creating unlinked stage2 subtrees Ricardo Koller
2023-03-12 11:06 ` Marc Zyngier [this message]
2023-03-13 22:23 ` Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 04/12] KVM: arm64: Add kvm_pgtable_stage2_split() Ricardo Koller
2023-03-12 11:35 ` Marc Zyngier
2023-03-13 23:58 ` Ricardo Koller
2023-03-15 18:09 ` Marc Zyngier
2023-03-15 18:51 ` Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 05/12] KVM: arm64: Refactor kvm_arch_commit_memory_region() Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 06/12] KVM: arm64: Add kvm_uninit_stage2_mmu() Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 07/12] KVM: arm64: Export kvm_are_all_memslots_empty() Ricardo Koller
2023-03-12 11:39 ` Marc Zyngier
2023-03-13 15:18 ` Sean Christopherson
2023-03-14 10:18 ` Marc Zyngier
2023-03-15 21:00 ` Sean Christopherson
2023-03-07 3:45 ` [PATCH v6 08/12] KVM: arm64: Add KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE Ricardo Koller
2023-03-12 11:56 ` Marc Zyngier
2023-03-24 7:41 ` Ricardo Koller
2023-03-29 4:50 ` Reiji Watanabe
2023-04-10 20:04 ` Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 09/12] KVM: arm64: Split huge pages when dirty logging is enabled Ricardo Koller
2023-03-12 12:54 ` Marc Zyngier
2023-04-10 18:32 ` Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 10/12] KVM: arm64: Open-code kvm_mmu_write_protect_pt_masked() Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 11/12] KVM: arm64: Split huge pages during KVM_CLEAR_DIRTY_LOG Ricardo Koller
2023-03-12 13:01 ` Marc Zyngier
2023-04-10 18:26 ` Ricardo Koller
2023-03-07 3:45 ` [PATCH v6 12/12] KVM: arm64: Use local TLBI on permission relaxation Ricardo Koller
2023-03-12 13:22 ` Marc Zyngier
2023-04-10 18:22 ` Ricardo Koller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87bkky5ivc.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=alexandru.elisei@arm.com \
--cc=andrew.jones@linux.dev \
--cc=bgardon@google.com \
--cc=catalin.marinas@arm.com \
--cc=dmatlack@google.com \
--cc=eric.auger@redhat.com \
--cc=gshan@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=oupton@google.com \
--cc=pbonzini@redhat.com \
--cc=qperret@google.com \
--cc=rananta@google.com \
--cc=reijiw@google.com \
--cc=ricarkol@gmail.com \
--cc=ricarkol@google.com \
--cc=seanjc@google.com \
--cc=shahuang@redhat.com \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.