[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210201190008.GI15632@willie-the-truck>
Date: Mon, 1 Feb 2021 19:00:08 +0000
From: Will Deacon <will@...nel.org>
To: Quentin Perret <qperret@...gle.com>
Cc: Catalin Marinas <catalin.marinas@....com>,
Marc Zyngier <maz@...nel.org>,
James Morse <james.morse@....com>,
Julien Thierry <julien.thierry.kdev@...il.com>,
Suzuki K Poulose <suzuki.poulose@....com>,
Rob Herring <robh+dt@...nel.org>,
Frank Rowand <frowand.list@...il.com>,
devicetree@...r.kernel.org, android-kvm@...gle.com,
linux-kernel@...r.kernel.org, kernel-team@...roid.com,
kvmarm@...ts.cs.columbia.edu, linux-arm-kernel@...ts.infradead.org,
Fuad Tabba <tabba@...gle.com>,
Mark Rutland <mark.rutland@....com>,
David Brazdil <dbrazdil@...gle.com>
Subject: Re: [RFC PATCH v2 10/26] KVM: arm64: Introduce an early Hyp page
allocator
On Fri, Jan 08, 2021 at 12:15:08PM +0000, Quentin Perret wrote:
> diff --git a/arch/arm64/kvm/hyp/nvhe/early_alloc.c b/arch/arm64/kvm/hyp/nvhe/early_alloc.c
> new file mode 100644
> index 000000000000..de4c45662970
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/nvhe/early_alloc.c
> @@ -0,0 +1,60 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2020 Google LLC
> + * Author: Quentin Perret <qperret@...gle.com>
> + */
> +
> +#include <asm/kvm_pgtable.h>
> +
> +#include <nvhe/memory.h>
> +
> +struct kvm_pgtable_mm_ops hyp_early_alloc_mm_ops;
> +s64 __ro_after_init hyp_physvirt_offset;
> +
> +static unsigned long base;
> +static unsigned long end;
> +static unsigned long cur;
> +
> +unsigned long hyp_early_alloc_nr_pages(void)
> +{
> + return (cur - base) >> PAGE_SHIFT;
> +}
nit: but I find this function name confusing (it's returning the number of
_allocated_ pages, not the number of _free_ pages!). How about something
like hyp_early_alloc_size() to match hyp_s1_pgtable_size() which you add
later? [and move the shift out to the caller]?
> +
> +extern void clear_page(void *to);
Stick this in a header?
> +
> +void *hyp_early_alloc_contig(unsigned int nr_pages)
I think order might make more sense, or do you need to allocate
non-power-of-2 batches of pages?
> +{
> + unsigned long ret = cur, i, p;
> +
> + if (!nr_pages)
> + return NULL;
> +
> + cur += nr_pages << PAGE_SHIFT;
> + if (cur > end) {
This would mean that concurrent hyp_early_alloc_nr_pages() would transiently
give the wrong answer. Might be worth sticking the locking expectations with
the function prototypes.
That said, maybe it would be better to write this check as:
if (end - cur < (nr_pages << PAGE_SHIFT))
as that also removes the need to worry about overflow if nr_pages is huge
(which would be a bug in the hypervisor, which we would then catch here).
> + cur = ret;
> + return NULL;
> + }
> +
> + for (i = 0; i < nr_pages; i++) {
> + p = ret + (i << PAGE_SHIFT);
> + clear_page((void *)(p));
> + }
> +
> + return (void *)ret;
> +}
> +
> +void *hyp_early_alloc_page(void *arg)
> +{
> + return hyp_early_alloc_contig(1);
> +}
> +
> +void hyp_early_alloc_init(unsigned long virt, unsigned long size)
> +{
> + base = virt;
> + end = virt + size;
> + cur = virt;
nit: base = cur = virt;
Will
Powered by blists - more mailing lists