From: christoffer.dall@linaro.org (Christoffer Dall)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v1 09/16] kvm: arm/arm64: Delay stage2 page table allocation
Date: Thu, 8 Feb 2018 12:01:14 +0100 [thread overview]
Message-ID: <20180208110114.GL29286@cbox> (raw)
In-Reply-To: <20180109190414.4017-10-suzuki.poulose@arm.com>
On Tue, Jan 09, 2018 at 07:04:04PM +0000, Suzuki K Poulose wrote:
> We allocate the entry level page tables for stage2 when the
> VM is created. This doesn't give us the flexibility of configuring
> the physical address space size for a VM. In order to allow
> the VM to choose the required size, we delay the allocation of
> stage2 entry level tables until we really try to map something.
>
> This could be either when the VM creates a memory range or when
> it tries to map a device memory. So we add in a hook to these
> two places to make sure the tables are allocated. We use
> kvm->slots_lock to serialize the allocation entry point, since
> we add hooks to the arch specific call back with the mutex held.
>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Christoffer Dall <cdall@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> virt/kvm/arm/arm.c | 18 ++++++----------
> virt/kvm/arm/mmu.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---------
> 2 files changed, 57 insertions(+), 22 deletions(-)
>
> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
> index 19b720ddedce..d06f00566664 100644
> --- a/virt/kvm/arm/arm.c
> +++ b/virt/kvm/arm/arm.c
> @@ -127,13 +127,13 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> for_each_possible_cpu(cpu)
> *per_cpu_ptr(kvm->arch.last_vcpu_ran, cpu) = -1;
>
> - ret = kvm_alloc_stage2_pgd(kvm);
> - if (ret)
> - goto out_fail_alloc;
> -
> ret = create_hyp_mappings(kvm, kvm + 1, PAGE_HYP);
> - if (ret)
> - goto out_free_stage2_pgd;
> + if (ret) {
> + free_percpu(kvm->arch.last_vcpu_ran);
> + kvm->arch.last_vcpu_ran = NULL;
> + return ret;
> + }
> +
>
> kvm_vgic_early_init(kvm);
>
> @@ -145,12 +145,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
>
> return ret;
> -out_free_stage2_pgd:
> - kvm_free_stage2_pgd(kvm);
> -out_fail_alloc:
> - free_percpu(kvm->arch.last_vcpu_ran);
> - kvm->arch.last_vcpu_ran = NULL;
> - return ret;
> }
>
> bool kvm_arch_has_vcpu_debugfs(void)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index c94c61ac38b9..257f2a8ccfc7 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -1011,15 +1011,39 @@ static int stage2_pmdp_test_and_clear_young(pmd_t *pmd)
> return stage2_ptep_test_and_clear_young((pte_t *)pmd);
> }
>
> -/**
> - * kvm_phys_addr_ioremap - map a device range to guest IPA
> - *
> - * @kvm: The KVM pointer
> - * @guest_ipa: The IPA at which to insert the mapping
> - * @pa: The physical address of the device
> - * @size: The size of the mapping
> +/*
> + * Finalise the stage2 page table layout. Must be called with kvm->slots_lock
> + * held.
> */
> -int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
> +static int __kvm_init_stage2_table(struct kvm *kvm)
> +{
> + /* Double check if somebody has already allocated it */
dubious comment: Either leave it out or explain that we need to check
again with the mutex held.
> + if (likely(kvm->arch.pgd))
> + return 0;
> + return kvm_alloc_stage2_pgd(kvm);
> +}
> +
> +static int kvm_init_stage2_table(struct kvm *kvm)
> +{
> + int rc;
> +
> + /*
> + * Once allocated, the stage2 entry level tables are only
> + * freed when the KVM instance is destroyed. So, if we see
> + * something valid here, that guarantees that we have
> + * done the one time allocation and it is something valid
> + * and won't go away until the last reference to the KVM
> + * is gone.
> + */
Really not sure if this comment adds something beyond what's described
by the code already?
Thanks,
-Christoffer
> + if (likely(kvm->arch.pgd))
> + return 0;
> + mutex_lock(&kvm->slots_lock);
> + rc = __kvm_init_stage2_table(kvm);
> + mutex_unlock(&kvm->slots_lock);
> + return rc;
> +}
> +
> +static int __kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
> phys_addr_t pa, unsigned long size, bool writable)
> {
> phys_addr_t addr, end;
> @@ -1055,6 +1079,23 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
> return ret;
> }
>
> +/**
> + * kvm_phys_addr_ioremap - map a device range to guest IPA.
> + * Acquires kvm->slots_lock for making sure that the stage2 is initialized.
> + *
> + * @kvm: The KVM pointer
> + * @guest_ipa: The IPA at which to insert the mapping
> + * @pa: The physical address of the device
> + * @size: The size of the mapping
> + */
> +int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
> + phys_addr_t pa, unsigned long size, bool writable)
> +{
> + if (unlikely(kvm_init_stage2_table(kvm)))
> + return -ENOMEM;
> + return __kvm_phys_addr_ioremap(kvm, guest_ipa, pa, size, writable);
> +}
> +
> static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap)
> {
> kvm_pfn_t pfn = *pfnp;
> @@ -1912,7 +1953,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
> goto out;
> }
>
> - ret = kvm_phys_addr_ioremap(kvm, gpa, pa,
> + ret = __kvm_phys_addr_ioremap(kvm, gpa, pa,
> vm_end - vm_start,
> writable);
> if (ret)
> @@ -1943,7 +1984,7 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
> int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
> unsigned long npages)
> {
> - return 0;
> + return __kvm_init_stage2_table(kvm);
> }
>
> void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots)
> --
> 2.13.6
>
next prev parent reply other threads:[~2018-02-08 11:01 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-09 19:03 [PATCH 00/16] kvm: arm64: Support for dynamic IPA size Suzuki K Poulose
2018-01-09 19:03 ` [PATCH v1 01/16] virtio: Validate queue pfn for 32bit transports Suzuki K Poulose
2018-01-09 23:29 ` Michael S. Tsirkin
2018-01-10 10:54 ` Suzuki K Poulose
2018-01-10 11:06 ` Michael S. Tsirkin
2018-01-10 11:18 ` Suzuki K Poulose
2018-01-10 11:19 ` Peter Maydell
2018-01-10 11:25 ` Jean-Philippe Brucker
2018-01-12 10:21 ` Peter Maydell
2018-01-12 11:01 ` Jean-Philippe Brucker
2018-01-10 11:30 ` Michael S. Tsirkin
2018-01-09 19:03 ` [PATCH v1 02/16] irqchip: gicv3-its: Add helpers for handling 52bit address Suzuki K Poulose
2018-02-07 15:10 ` Christoffer Dall
2018-02-08 11:20 ` Suzuki K Poulose
2018-02-08 11:36 ` Robin Murphy
2018-02-08 13:45 ` Christoffer Dall
2018-01-09 19:03 ` [PATCH v1 03/16] arm64: Make page table helpers reusable Suzuki K Poulose
2018-01-09 19:03 ` [PATCH v1 04/16] arm64: Refactor pud_huge for reusability Suzuki K Poulose
2018-01-09 19:04 ` [PATCH v1 05/16] arm64: Helper for parange to PASize Suzuki K Poulose
2018-02-08 11:00 ` Christoffer Dall
2018-02-08 11:08 ` Suzuki K Poulose
2018-02-08 11:21 ` Christoffer Dall
2018-01-09 19:04 ` [PATCH v1 06/16] kvm: arm/arm64: Fix stage2_flush_memslot for 4 level page table Suzuki K Poulose
2018-02-08 11:00 ` Christoffer Dall
2018-01-09 19:04 ` [PATCH v1 07/16] kvm: arm/arm64: Remove spurious WARN_ON Suzuki K Poulose
2018-02-08 11:00 ` Christoffer Dall
2018-01-09 19:04 ` [PATCH v1 08/16] kvm: arm/arm64: Clean up stage2 pgd life time Suzuki K Poulose
2018-02-08 11:00 ` Christoffer Dall
2018-02-08 17:19 ` Suzuki K Poulose
2018-02-09 8:11 ` Christoffer Dall
2018-01-09 19:04 ` [PATCH v1 09/16] kvm: arm/arm64: Delay stage2 page table allocation Suzuki K Poulose
2018-02-08 11:01 ` Christoffer Dall [this message]
2018-02-08 17:20 ` Suzuki K Poulose
2018-01-09 19:04 ` [PATCH v1 10/16] kvm: arm/arm64: Prepare for VM specific stage2 translations Suzuki K Poulose
2018-01-09 19:04 ` [PATCH v1 11/16] kvm: arm64: Make stage2 page table layout dynamic Suzuki K Poulose
2018-01-09 19:04 ` [PATCH v1 12/16] kvm: arm64: Dynamic configuration of VTCR and VTTBR mask Suzuki K Poulose
2018-01-09 19:04 ` [PATCH v1 13/16] kvm: arm64: Configure VTCR per VM Suzuki K Poulose
2018-02-08 18:04 ` Christoffer Dall
2018-03-15 15:24 ` Suzuki K Poulose
2018-01-09 19:04 ` [PATCH v1 14/16] kvm: arm64: Switch to per VM IPA Suzuki K Poulose
2018-02-08 11:00 ` Christoffer Dall
2018-02-08 17:22 ` Suzuki K Poulose
2018-02-09 8:12 ` Christoffer Dall
2018-01-09 19:04 ` [PATCH v1 15/16] kvm: arm64: Allow configuring physical address space size Suzuki K Poulose
2018-02-08 11:14 ` Christoffer Dall
2018-02-08 17:53 ` Suzuki K Poulose
2018-02-09 8:16 ` Christoffer Dall
2018-02-09 9:27 ` Andrew Jones
2018-03-15 11:06 ` Suzuki K Poulose
2018-01-09 19:04 ` [PATCH v1 16/16] vgic: its: Add support for 52bit guest physical address Suzuki K Poulose
2018-01-09 19:04 ` [kvmtool hack 1/3] virtio: Handle aborts using invalid PFN Suzuki K Poulose
2018-01-09 19:04 ` [kvmtool hack 2/3] kvmtool: arm64: Add support for guest physical address size Suzuki K Poulose
2018-01-09 19:04 ` [kvmtool hack 3/3] kvmtool: arm64: Switch memory layout Suzuki K Poulose
2018-02-08 11:18 ` [PATCH 00/16] kvm: arm64: Support for dynamic IPA size Christoffer Dall
2018-02-08 11:25 ` Will Deacon
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=20180208110114.GL29286@cbox \
--to=christoffer.dall@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).