From patchwork Fri Jul 8 21:21:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12911894 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 87D7EC43334 for ; Fri, 8 Jul 2022 21:22:25 +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=N4uHlcf2Kf2AFCFRgcyELM/818dpQw5hXqtwvlKQhSc=; b=2Tdsff74p0XGU4GTV8xU5hJXbd z7wQgSu00WdYFIquzKPWxTwm+EzvOdavZspHhk1qssgajbDBkL4P6R/kzYCkqvjkMKc9uFwpp34U+ O81rFeQUnKMDaeFc6c7uKedf/7RtK0WxwJMXTTBK/R2tfNhJkwdZ6Q9zJAzvgU4p+L+8SjkE3kY9g p4RG6LElU4ATTIGg8bgxQ23Ny4n2hbD6ELH4cy3sdJ/k82/RTt57dNRudldeC2Cpjqqq3VRaHcMPt uIDDsbpTElripeJ3w6TQ1W7qU7rLenVmEZFj7HYCVu3o4u8P3SYs8Osw8BKl9u9rGiBTbCG3Pv+NQ ZyJnt2/A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1o9vPe-0060gW-9W; Fri, 08 Jul 2022 21:21:22 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1o9vPa-0060eo-GS for linux-arm-kernel@lists.infradead.org; Fri, 08 Jul 2022 21:21:19 +0000 Received: by mail-yb1-xb49.google.com with SMTP id k13-20020a25240d000000b0066e32c61c25so12520712ybk.3 for ; Fri, 08 Jul 2022 14:21:17 -0700 (PDT) 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=twUVJxIVhhRUka3ujAGpgx5jyolc6+CWViYPAjBE+SE=; b=gGW7BYWFyEalfApr15oYFvpIMQcxD7X1mQiNqiPuiVHYYUJgo4j9T8+HQrwKcnXi4E uEYEIa6xfRlrn0clPA2WDvMuAzqAf91T7W2xQHSARkmZ8P1Lz2oyGz5DLXF4tH9Ry9TJ NSulr8r64BRrltG4I9PBO5kezDuJpeqU5FtSpSKwFcouadKfcfrj2G0ftpInI2imZOKz SM+n0KcxkrqAmu334mXP1Menw+lX76bcByeebg6rmKPRCwX4ejI7DrvTf6emYPf0kcHg /DgDGUJ4pRWEXgIDl2tKPrWdfeRCoIuV6Znk/PyHVb51PY7O7o//T5G4QkZZXL6unvXn Qp2g== 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=twUVJxIVhhRUka3ujAGpgx5jyolc6+CWViYPAjBE+SE=; b=vaFolJGqWvosCJ8IlKV3uaUt5RF/nLGpIHc7HCr6bcnCl2jDjoGMjxY8Xd7E5Pj5Pm GlM3Busw0OUF3sn0Dn8103JaPb8wZA2R7obWJM5fNbKe9Hurn6nS7hcIH6PS3fPkTQGd 6S8ZKqXx1sptqp4CdeDqwMrPUKe5aensRO1Zn39avBJ3UvvzRkQwtGXQzJnYzHaeS1A3 UoMFTmRd3XhBMtMOICs6qLu0Jbf1Prkr55rD6IKPemaJG20grY16Q4bFOta9/lxBMud5 SX1M3MBdbOyX5hbBW4GRyADx7kAaYajUaLxEtdaI4tAKQWMOy2YhLh+ZMzI3qIsl+YvE wMAA== X-Gm-Message-State: AJIora9+QHTX7zVex970K9+NwxGl3jAa9N29xgVcV6hBFrYcJ4c0edwp HsuFM4DBl1qSzauiB3miJY2qkp8= X-Google-Smtp-Source: AGRyM1sGe6ArR8ij03wbQdy/kCKJfdsfrfRo/UOh8N3xvvxXsh3eCjHm+5S8mVUGa8PtuJjzKsK3bH4= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:ff27:d65:6bb8:b084]) (user=pcc job=sendgmr) by 2002:a81:4eca:0:b0:31c:7a6a:f6d3 with SMTP id c193-20020a814eca000000b0031c7a6af6d3mr6573793ywb.82.1657315276782; Fri, 08 Jul 2022 14:21:16 -0700 (PDT) Date: Fri, 8 Jul 2022 14:21:04 -0700 In-Reply-To: <20220708212106.325260-1-pcc@google.com> Message-Id: <20220708212106.325260-2-pcc@google.com> Mime-Version: 1.0 References: <20220708212106.325260-1-pcc@google.com> X-Mailer: git-send-email 2.37.0.144.g8ac04bfd2-goog Subject: [PATCH v2 1/3] KVM: arm64: add a hypercall for disowning pages From: Peter Collingbourne To: kvmarm@lists.cs.columbia.edu Cc: Peter Collingbourne , Marc Zyngier , kvm@vger.kernel.org, Andy Lutomirski , linux-arm-kernel@lists.infradead.org, Michael Roth , Catalin Marinas , Chao Peng , Will Deacon , Evgenii Stepanov X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220708_142118_563768_4099E0FE X-CRM114-Status: GOOD ( 13.21 ) 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 Currently we only deny the host access to hyp and guest pages. However, there may be other pages that could potentially be used to indirectly compromise the hypervisor or the other guests. Therefore introduce a __pkvm_disown_pages hypercall that the host kernel may use to deny its future self access to those pages before deprivileging itself. Signed-off-by: Peter Collingbourne --- v2: - refcount the PTEs owned by NOBODY arch/arm64/include/asm/kvm_asm.h | 1 + arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 + arch/arm64/kvm/hyp/include/nvhe/pkvm.h | 1 + arch/arm64/kvm/hyp/nvhe/hyp-main.c | 9 +++++++++ arch/arm64/kvm/hyp/nvhe/mem_protect.c | 11 +++++++++++ 5 files changed, 23 insertions(+) diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 411cfbe3ebbd..1a177d9ed517 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -63,6 +63,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa, __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid, __KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context, + __KVM_HOST_SMCCC_FUNC___pkvm_disown_pages, __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize, /* Hypercalls available after pKVM finalisation */ diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index e0bbb1726fa3..e88a9dab9cd5 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -58,6 +58,7 @@ enum pkvm_component_id { PKVM_ID_HOST, PKVM_ID_HYP, PKVM_ID_GUEST, + PKVM_ID_NOBODY, }; extern unsigned long hyp_nr_cpus; diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h index c1987115b217..fbd991a46ab3 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h @@ -98,6 +98,7 @@ int __pkvm_init_shadow(struct kvm *kvm, unsigned long pgd_hva, unsigned long last_ran_hva, size_t last_ran_size); int __pkvm_teardown_shadow(unsigned int shadow_handle); +int __pkvm_disown_pages(phys_addr_t phys, size_t size); struct kvm_shadow_vcpu_state * pkvm_load_shadow_vcpu_state(unsigned int shadow_handle, unsigned int vcpu_idx); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index e575224244e6..0dab343734e8 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -1031,6 +1031,14 @@ static void handle___pkvm_teardown_shadow(struct kvm_cpu_context *host_ctxt) cpu_reg(host_ctxt, 1) = __pkvm_teardown_shadow(shadow_handle); } +static void handle___pkvm_disown_pages(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(phys_addr_t, phys, host_ctxt, 1); + DECLARE_REG(size_t, size, host_ctxt, 2); + + cpu_reg(host_ctxt, 1) = __pkvm_disown_pages(phys, size); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x @@ -1048,6 +1056,7 @@ static const hcall_t host_hcall[] = { HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), HANDLE_FUNC(__kvm_tlb_flush_vmid), HANDLE_FUNC(__kvm_flush_cpu_context), + HANDLE_FUNC(__pkvm_disown_pages), HANDLE_FUNC(__pkvm_prot_finalize), HANDLE_FUNC(__pkvm_host_share_hyp), diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index d839bb573b49..b3a2ad8454cc 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -1756,3 +1756,14 @@ int __pkvm_host_reclaim_page(u64 pfn) return ret; } + +int __pkvm_disown_pages(phys_addr_t phys, size_t size) +{ + int ret; + + host_lock_component(); + ret = host_stage2_set_owner_locked(phys, size, PKVM_ID_NOBODY); + host_unlock_component(); + + return ret; +}