From patchwork Wed Dec 15 16:12:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Perret X-Patchwork-Id: 12696303 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C8EF9C433F5 for ; Wed, 15 Dec 2021 16:28:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=n0Eu5eYIk92LJP8+bmly4b5Q3qjT9irEm+rUedv5tIE=; b=nhxhASbBs0w1qbZFTk8okQUuHN TisTXVgXqqBDIl7IivLmGKZ41Ldo3QBRcMsnruPga/jlVlGgNm3EuVBXyBSmvKJN95otoNUVOCYnh 2huNh6AVQb6iB8qaYh0UMaPRgcTbMFAozLzcydIqcy8jVTR/ldnAKlpUZukbwLdQM0pml9OdkxWSY OQQlCP/AGKb+TwpvJtGSI0Ul1OpYELXy3Z0Y0JAmGKG3/m9ms61P1WAb1E28hATq6wEPvfpsLoddC INMXkwJ/iH9MPPbKhKpdxDV2x5D68k621WFfBLA3VIe1D4gN/dk67SVwlIt9B+w1tWv86mbAg2g5P vcTxYjHw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mxX7O-001hnj-5S; Wed, 15 Dec 2021 16:27:02 +0000 Received: from mail-wr1-x44a.google.com ([2a00:1450:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mxWtr-001c81-K9 for linux-arm-kernel@lists.infradead.org; Wed, 15 Dec 2021 16:13:05 +0000 Received: by mail-wr1-x44a.google.com with SMTP id n22-20020adf8b16000000b001a22f61b29cso647378wra.23 for ; Wed, 15 Dec 2021 08:13:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=rFCgXqXfHcb53cslJUDyyHetn7RW83DsGSg8T2DxbyQ=; b=Xbr7DWM55kmOvaqO2GbH+6Sgs0CZAnYI3TRkt/YXsdzrrqRLR/Frivi1pl3MLM/9FO j32SKpbCf8SMAOreeXObyBZiz1VTWrQXYlgdUzSK3UiwwzgzmnLA68Y25V9KvNe9N0XM 3kATi2Bbx3vrZyX/PezVQ1WnN0Gk6aVxD4zGCkhLD1gF+4QZzAYxOzBciVqN/KtL6qfr MFVCuO9PnWIyhUmJBVrBtkUcwW0Z5HXykLMP1ZqnW8V88b5/b0Ui7fr3FWkM7uhAOked VYssIEAFzkGEPZ41vDG5Cmqg5RHUxdorN+UUKPO33aMzZ3HokfsdK3D8CBYofIZozEZB 1Dqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=rFCgXqXfHcb53cslJUDyyHetn7RW83DsGSg8T2DxbyQ=; b=iOYyt/q24FR8L0gaMLfcHhNMTHFmRlCLhp+bc2aVnpNhRifyNX/GPVBwNOqvYj2L8t 0wa+tT8CJC92LmnKXpxKakztiCeyx1scymvSl5nEZ0Zokd48VOo9BpXzUdJDb9yygl+G pL8yU2W9K/kQa0k4VoSMeMlcaN+8bofn0XJ7JwcasvSHPCOE/Rxd8dVomsAVi7yF8QIa h/EIk3Q9mjbWGcq5TS1KLtkwV0Z8GA6n1jnS4S1ks9yFm0+ivLZ3cG04AJFW2GCZTBXP Fapfdf8NY+vrijUHdpASEpA493wpJGKQgZ/oofm6VPRgnaMjiB6nlNfyL29uNqz+0p7C H9IQ== X-Gm-Message-State: AOAM532Frq+IhJeVN1VP4Fxdix9hO7InhtQPIyqDb66ZADOsciNYNgDG znc8875HB0w4/eTPJkZ1VRu60sy8ge+6 X-Google-Smtp-Source: ABdhPJy2AtmIuThch2i8/F0tSR53ROmxY1v/z1N9Cj4IaXOuDPzVJjxAElkrPPF8sn6zBbpFTeC0kXQ/6Ul+ X-Received: from luke.lon.corp.google.com ([2a00:79e0:d:210:fc03:4f5b:4e9b:3ec1]) (user=qperret job=sendgmr) by 2002:a5d:4804:: with SMTP id l4mr4979766wrq.629.1639584781079; Wed, 15 Dec 2021 08:13:01 -0800 (PST) Date: Wed, 15 Dec 2021 16:12:23 +0000 In-Reply-To: <20211215161232.1480836-1-qperret@google.com> Message-Id: <20211215161232.1480836-7-qperret@google.com> Mime-Version: 1.0 References: <20211215161232.1480836-1-qperret@google.com> X-Mailer: git-send-email 2.34.1.173.g76aa8bc2d0-goog Subject: [PATCH v4 06/14] KVM: arm64: Introduce kvm_share_hyp() From: Quentin Perret To: Marc Zyngier , James Morse , Alexandru Elisei , Suzuki K Poulose , Catalin Marinas , Will Deacon Cc: qperret@google.com, qwandor@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kernel-team@android.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211215_081303_762372_75EF6950 X-CRM114-Status: GOOD ( 19.61 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The create_hyp_mappings() function can currently be called at any point in time. However, its behaviour in protected mode changes widely depending on when it is being called. Prior to KVM init, it is used to create the temporary page-table used to bring-up the hypervisor, and later on it is transparently turned into a 'share' hypercall when the kernel has lost control over the hypervisor stage-1. In order to prepare the ground for also unsharing pages with the hypervisor during guest teardown, introduce a kvm_share_hyp() function to make it clear in which places a share hypercall should be expected, as we will soon need a matching unshare hypercall in all those places. Signed-off-by: Quentin Perret --- arch/arm64/include/asm/kvm_mmu.h | 1 + arch/arm64/kvm/arm.c | 4 ++-- arch/arm64/kvm/fpsimd.c | 2 +- arch/arm64/kvm/mmu.c | 27 +++++++++++++++++++++------ arch/arm64/kvm/reset.c | 2 +- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 02d378887743..185d0f62b724 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -150,6 +150,7 @@ static __always_inline unsigned long __kern_hyp_va(unsigned long v) #include #include +int kvm_share_hyp(void *from, void *to); int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot); int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size, void __iomem **kaddr, diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 9b745d2bc89a..c202abb448b1 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -146,7 +146,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (ret) return ret; - ret = create_hyp_mappings(kvm, kvm + 1, PAGE_HYP); + ret = kvm_share_hyp(kvm, kvm + 1); if (ret) goto out_free_stage2_pgd; @@ -342,7 +342,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) if (err) return err; - return create_hyp_mappings(vcpu, vcpu + 1, PAGE_HYP); + return kvm_share_hyp(vcpu, vcpu + 1); } void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c index 5526d79c7b47..86899d3aa9a9 100644 --- a/arch/arm64/kvm/fpsimd.c +++ b/arch/arm64/kvm/fpsimd.c @@ -30,7 +30,7 @@ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu) struct user_fpsimd_state *fpsimd = ¤t->thread.uw.fpsimd_state; /* Make sure the host task fpsimd state is visible to hyp: */ - ret = create_hyp_mappings(fpsimd, fpsimd + 1, PAGE_HYP); + ret = kvm_share_hyp(fpsimd, fpsimd + 1); if (!ret) vcpu->arch.host_fpsimd_state = kern_hyp_va(fpsimd); diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index ea840fa223b5..872137fb5e0f 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -299,6 +299,25 @@ static int pkvm_share_hyp(phys_addr_t start, phys_addr_t end) return 0; } +int kvm_share_hyp(void *from, void *to) +{ + if (is_kernel_in_hyp_mode()) + return 0; + + /* + * The share hcall maps things in the 'fixed-offset' region of the hyp + * VA space, so we can only share physically contiguous data-structures + * for now. + */ + if (is_vmalloc_or_module_addr(from) || is_vmalloc_or_module_addr(to)) + return -EINVAL; + + if (kvm_host_owns_hyp_mappings()) + return create_hyp_mappings(from, to, PAGE_HYP); + + return pkvm_share_hyp(__pa(from), __pa(to)); +} + /** * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode * @from: The virtual kernel start address of the range @@ -319,12 +338,8 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot) if (is_kernel_in_hyp_mode()) return 0; - if (!kvm_host_owns_hyp_mappings()) { - if (WARN_ON(prot != PAGE_HYP)) - return -EPERM; - return pkvm_share_hyp(kvm_kaddr_to_phys(from), - kvm_kaddr_to_phys(to)); - } + if (!kvm_host_owns_hyp_mappings()) + return -EPERM; start = start & PAGE_MASK; end = PAGE_ALIGN(end); diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index c7a0249df840..e3e2a79fbd75 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -113,7 +113,7 @@ static int kvm_vcpu_finalize_sve(struct kvm_vcpu *vcpu) if (!buf) return -ENOMEM; - ret = create_hyp_mappings(buf, buf + reg_sz, PAGE_HYP); + ret = kvm_share_hyp(buf, buf + reg_sz); if (ret) { kfree(buf); return ret;