Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp478113pxf; Wed, 10 Mar 2021 10:00:07 -0800 (PST) X-Google-Smtp-Source: ABdhPJz1mNBNf6NOYwgAuEis6ifUfnVHSXCIM5JlYMWzVrFLFGYKric/8TI9NGUb2JpIqgzXdUzV X-Received: by 2002:a17:906:9442:: with SMTP id z2mr5194366ejx.79.1615399207196; Wed, 10 Mar 2021 10:00:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615399207; cv=none; d=google.com; s=arc-20160816; b=qU2q4pYc/bdhVPF7jmTPkz3Gyrl/GjXY3IgvU7GVnEyf2WAhmA3ffkzhJBiw+DwVwE ABgiphueXxcd34Ta9AE/ZBAFEpRNXg0rdXh58CUDgukz/G0Eu2qp8C6YhRGj6X1VOyE4 ZvULCnepa7KTL/vle02r8bCaSPki3dRVFegypSWdSu2KUk8XrtR/TNzCbExPxeJWAyQI gkMuMm4GWcazkVi4v/86BLdzTHmjrUnVlqnsEkx2pQCAB6ROqOwu7ZMx9oemRT88wTuH HIZSJtGOE0rWd8OQQ/NHzrhEL/3RvV7FAASyOsrrmLfzPlJsTtYx8H8ys/iQGXaggRPV kIDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=VP8mf4K4lbKPxoOK4Eqb7s/YbwLsns2Dk6uqu7xpKg4=; b=ird5gYhUYaQWd7RbFUJdZ95g+TJ8JhjGNfBgbgbAmYCky51lNWd4uRgua2oqrlESXa oFjdSeVncVhV9PvgV/eL8AQYCp3zcSCkje8QEFQ5LOGjHS/eBB3kbqZsX7n4uLgrvhlQ AEvGGqM6wbOPl1lhRA8oGzDCiHFKPubi39VaOdtkxMKxs1ZxPv8SWi0bc0QW3YNthQST T6xnNHCGHpfnM0XVegqwxk3hN6NUzwofOslebSudXJejeGf0czRH/LWdOuIguRIQKVoN ohhIxMF0AbCbL1PE40qU1WZxilTvBS9jot59wnrUEgYPJ5b1QUk/LHA6lRpkJh5t7Icv 6Yhw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=lii4hE0N; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o4si90219edc.426.2021.03.10.09.59.44; Wed, 10 Mar 2021 10:00:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=lii4hE0N; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233717AbhCJR6s (ORCPT + 99 others); Wed, 10 Mar 2021 12:58:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48754 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233461AbhCJR6R (ORCPT ); Wed, 10 Mar 2021 12:58:17 -0500 Received: from mail-wr1-x44a.google.com (mail-wr1-x44a.google.com [IPv6:2a00:1450:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F39BEC061760 for ; Wed, 10 Mar 2021 09:58:16 -0800 (PST) Received: by mail-wr1-x44a.google.com with SMTP id e29so8313916wra.12 for ; Wed, 10 Mar 2021 09:58:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=VP8mf4K4lbKPxoOK4Eqb7s/YbwLsns2Dk6uqu7xpKg4=; b=lii4hE0NwlVugsKpM5UCLRkqnlSVsbBClXn1iNHrkaI3eox7X7nnAghzxeMAc8ylT6 hweHM0U1Etxj/ih8weub/puP6IvFHyRYyneOPy75qjQJQmIYzO+q5IZXtWu7QShmzcgj LnpMztYUkVYMY+erd5BKQGyWcOxR8z3MIO+3vFKDpbzNZ/AUG0aLe0CVeOzNozu4d7at pjBnwOU7ON2vG8KlxWm2BTkbhe4D0R7o98HB5G0ovo+JTwcShKkiZYCX9yv74ebNvhU5 1D9WrNDdAwlsXZ3cufbxN+zv0FpNw1vKBPYmtzrWXKAKm29h5BMjIM9Yrtzjirpao2hE imJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=VP8mf4K4lbKPxoOK4Eqb7s/YbwLsns2Dk6uqu7xpKg4=; b=MS+jh/lfqBMIaUBe1qpK13TXagYWRLRYJ9TC7TbIlBgrmLVK5twtVsLH3BeFmlYLmC J2iGRvtc1XfY5CwvcKucDOSQ4CULilpjeP/KnlvZFbyh9TJ3lUiyWfpHeFw7VqWw2O1p /A+BteL0P3stn4bz2ZtGp8UGWI3ze0XM7P+JOtW0SC+rMZGaM6hP037fEj/DqTgQRi5M 1Y0mEvLeBviAUgzs4kjgqy/INW4ZdjQQCEugRdgJ1HLLvkSD85wUo373uRl0DM6zno+y 9TIzn08mmIRvgFLjmxa1AbQahwVUmRrYS4o+XgIvyvQ7hyEsy9cUYiSq0Wi6pJvCqwOe 9ljQ== X-Gm-Message-State: AOAM530b3p8HR5tWb19PSZ1Nuz3gJaYYNUg0MN3Vy/D2N87zMQmaTjz3 Pna0slEzbmsw97x628PsmCH+0+3Yn6Zc X-Received: from r2d2-qp.c.googlers.com ([fda3:e722:ac3:10:28:9cb1:c0a8:1652]) (user=qperret job=sendgmr) by 2002:adf:d84d:: with SMTP id k13mr4901235wrl.164.1615399095727; Wed, 10 Mar 2021 09:58:15 -0800 (PST) Date: Wed, 10 Mar 2021 17:57:27 +0000 In-Reply-To: <20210310175751.3320106-1-qperret@google.com> Message-Id: <20210310175751.3320106-11-qperret@google.com> Mime-Version: 1.0 References: <20210310175751.3320106-1-qperret@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH v4 10/34] KVM: arm64: Introduce an early Hyp page allocator From: Quentin Perret To: catalin.marinas@arm.com, will@kernel.org, maz@kernel.org, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com Cc: android-kvm@google.com, linux-kernel@vger.kernel.org, kernel-team@android.com, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, tabba@google.com, mark.rutland@arm.com, dbrazdil@google.com, mate.toth-pal@arm.com, seanjc@google.com, qperret@google.com, robh+dt@kernel.org, ardb@kernel.org Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org With nVHE, the host currently creates all stage 1 hypervisor mappings at EL1 during boot, installs them at EL2, and extends them as required (e.g. when creating a new VM). But in a world where the host is no longer trusted, it cannot have full control over the code mapped in the hypervisor. In preparation for enabling the hypervisor to create its own stage 1 mappings during boot, introduce an early page allocator, with minimal functionality. This allocator is designed to be used only during early bootstrap of the hyp code when memory protection is enabled, which will then switch to using a full-fledged page allocator after init. Acked-by: Will Deacon Signed-off-by: Quentin Perret --- arch/arm64/kvm/hyp/include/nvhe/early_alloc.h | 14 +++++ arch/arm64/kvm/hyp/include/nvhe/memory.h | 24 +++++++++ arch/arm64/kvm/hyp/nvhe/Makefile | 2 +- arch/arm64/kvm/hyp/nvhe/early_alloc.c | 54 +++++++++++++++++++ arch/arm64/kvm/hyp/nvhe/psci-relay.c | 4 +- 5 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 arch/arm64/kvm/hyp/include/nvhe/early_alloc.h create mode 100644 arch/arm64/kvm/hyp/include/nvhe/memory.h create mode 100644 arch/arm64/kvm/hyp/nvhe/early_alloc.c diff --git a/arch/arm64/kvm/hyp/include/nvhe/early_alloc.h b/arch/arm64/kvm/hyp/include/nvhe/early_alloc.h new file mode 100644 index 000000000000..dc61aaa56f31 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/early_alloc.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __KVM_HYP_EARLY_ALLOC_H +#define __KVM_HYP_EARLY_ALLOC_H + +#include + +void hyp_early_alloc_init(void *virt, unsigned long size); +unsigned long hyp_early_alloc_nr_used_pages(void); +void *hyp_early_alloc_page(void *arg); +void *hyp_early_alloc_contig(unsigned int nr_pages); + +extern struct kvm_pgtable_mm_ops hyp_early_alloc_mm_ops; + +#endif /* __KVM_HYP_EARLY_ALLOC_H */ diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h new file mode 100644 index 000000000000..3e49eaa7e682 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __KVM_HYP_MEMORY_H +#define __KVM_HYP_MEMORY_H + +#include + +#include + +extern s64 hyp_physvirt_offset; + +#define __hyp_pa(virt) ((phys_addr_t)(virt) + hyp_physvirt_offset) +#define __hyp_va(phys) ((void *)((phys_addr_t)(phys) - hyp_physvirt_offset)) + +static inline void *hyp_phys_to_virt(phys_addr_t phys) +{ + return __hyp_va(phys); +} + +static inline phys_addr_t hyp_virt_to_phys(void *addr) +{ + return __hyp_pa(addr); +} + +#endif /* __KVM_HYP_MEMORY_H */ diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile index bc98f8e3d1da..24ff99e2eac5 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -13,7 +13,7 @@ lib-objs := clear_page.o copy_page.o memcpy.o memset.o lib-objs := $(addprefix ../../../lib/, $(lib-objs)) obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \ - hyp-main.o hyp-smp.o psci-relay.o + hyp-main.o hyp-smp.o psci-relay.o early_alloc.o obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ ../fpsimd.o ../hyp-entry.o ../exception.o obj-y += $(lib-objs) 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..1306c430ab87 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/early_alloc.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Google LLC + * Author: Quentin Perret + */ + +#include + +#include +#include + +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_used_pages(void) +{ + return (cur - base) >> PAGE_SHIFT; +} + +void *hyp_early_alloc_contig(unsigned int nr_pages) +{ + unsigned long size = (nr_pages << PAGE_SHIFT); + void *ret = (void *)cur; + + if (!nr_pages) + return NULL; + + if (end - cur < size) + return NULL; + + cur += size; + memset(ret, 0, size); + + return ret; +} + +void *hyp_early_alloc_page(void *arg) +{ + return hyp_early_alloc_contig(1); +} + +void hyp_early_alloc_init(void *virt, unsigned long size) +{ + base = cur = (unsigned long)virt; + end = base + size; + + hyp_early_alloc_mm_ops.zalloc_page = hyp_early_alloc_page; + hyp_early_alloc_mm_ops.phys_to_virt = hyp_phys_to_virt; + hyp_early_alloc_mm_ops.virt_to_phys = hyp_virt_to_phys; +} diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe/psci-relay.c index 63de71c0481e..08508783ec3d 100644 --- a/arch/arm64/kvm/hyp/nvhe/psci-relay.c +++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c @@ -11,6 +11,7 @@ #include #include +#include #include void kvm_hyp_cpu_entry(unsigned long r0); @@ -20,9 +21,6 @@ void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); /* Config options set by the host. */ struct kvm_host_psci_config __ro_after_init kvm_host_psci_config; -s64 __ro_after_init hyp_physvirt_offset; - -#define __hyp_pa(x) ((phys_addr_t)((x)) + hyp_physvirt_offset) #define INVALID_CPU_ID UINT_MAX -- 2.30.1.766.gb4fecdf3b7-goog