From patchwork Thu Mar 6 11:00:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004234 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 6EF11C282D1 for ; Thu, 6 Mar 2025 11:04:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=j3EIDfh3bzz6FZ09T3hzG7XWiQpkIRvJOzVpoxagQuo=; b=o5iS1PaRgdg5+4wXfuPqUq8gBf 6Jfa3T1cPaFTkji/HLc85ke1WbNltgSTA9DpKJhEXYAFcOVA9zIjHU3wk7224s1lSGQ8Ef/DdE3iz LecM2ywsfwdIeEay7J0kWr0u+ZM4ivwms06IRA/Wcdgq9CWie97QrhuPqsqLihAIelrSBg3TkCeHP mLAorjndR/cioV2zylUHBG0pdzaF7NAui1TCqwat7sKGDdZb4+EmmIRfCHQ3OZDYUFWtTzCQPdgFW 7GL07z/pZhorws8FEpQHtJ8buzrQvkKC3qY1CgNtnPTKjC02FV++NYqLrHhYfvPAFeGXUBQa9Rh+Y az51//uw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tq91I-0000000Aj4O-3YyW; Thu, 06 Mar 2025 11:04:04 +0000 Received: from mail-wm1-x349.google.com ([2a00:1450:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8y9-0000000AiVx-39J4 for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:00:50 +0000 Received: by mail-wm1-x349.google.com with SMTP id 5b1f17b1804b1-43bc97e6360so2240955e9.3 for ; Thu, 06 Mar 2025 03:00:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258847; x=1741863647; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=j3EIDfh3bzz6FZ09T3hzG7XWiQpkIRvJOzVpoxagQuo=; b=KxkVPfwItOM85BanyxsI1SaQY2POTILUAvN1I1qQCvTHZbfUOOu0GOMlJwUrVO+9VH 7c++DZbnOKV+BMWw/iMQBG/yWf9c25+QaktsU48NvdgZ1kZ5iLCR8ajiyr9Abt4ELRjm A870PDrxHpTaaqVwyEh7eixwobYN9CES8868apRgio3arw2cx/AmmzJZ7edFjjByQ2ga cFaQq8ROv+63VLI3O2aF72aMiYp7uPTl1BPPLpxzm9f+/znGD4RrFvLnUX9d4ly2EM9A FgGtbL6S5cfrbehLCvoO8pFs8ZjGSzyMYP+/5ZEnAN5dhUu0dKfhM9vwZ5PjVilLxdUv k6Jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258847; x=1741863647; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=j3EIDfh3bzz6FZ09T3hzG7XWiQpkIRvJOzVpoxagQuo=; b=ns03NxfZ9DiQXfu18LIWwR9hWEdz528/lod2WK6dnHcWNBdReX/G4ir95YWZ78v7nc +i9M9iy3OMp8+s9Paki/ztn4gW54WhZv5AkLJJWT1e+Lc5SCMfok5i8ATu+q5mq9vitA +q3dODvxCetMXciZ3ElFeyxipIrhBvk1vDHop83j/89j2t0uVqV2g/qRtRwUoKbKo/MJ cpks/SiR0QZHGdNYoGnhRx67S38Og22/zcAGbmYAbJnjMdBQfu5czMYcyldgm1hh3rz7 uOI2coWH+nCcHBlaAmeI362ZVbp9b9vDwJMEMNzF4P1x/vTMZ4NLGkZksqoCa0ZX3h4T +I5w== X-Forwarded-Encrypted: i=1; AJvYcCXpO4ZEL2a/H/Sm/b2mf9Kv/nfQsI9PM9Iphwlidt5y1MdqHU2B4nuEqcqJrtFmp62PV4CQdluNRXb+zz4tQiHs@lists.infradead.org X-Gm-Message-State: AOJu0YydXv5ernqUEBlNvZ4C0GRPOgn5Ls/O9PihgxsQWyYJkVvuKUKp CTx/CNWnboXz0Ke8xoqqqQlODsHF41IEt+s+ksv061n9f/owBOaZn8AwVxcpSGQ04Cs+4e4wnX3 AslQZoljr3QotPF9T6w== X-Google-Smtp-Source: AGHT+IHc9gvpZKIAvFGYxWaWiTqhy0gbG8Wikxg2XkAF/4yfzSNV6Mp0Ztsi5081XwxCLqL618nGLsdLrgFavXUx X-Received: from wmgg12.prod.google.com ([2002:a05:600d:c:b0:43b:d4fc:1dee]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3b95:b0:43b:cfbb:3806 with SMTP id 5b1f17b1804b1-43bd29d2d84mr55969355e9.14.1741258847657; Thu, 06 Mar 2025 03:00:47 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:30 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-2-vdonnefort@google.com> Subject: [PATCH v2 1/9] KVM: arm64: Handle huge mappings for np-guest CMOs From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030049_787067_30A26DA3 X-CRM114-Status: UNSURE ( 9.12 ) X-CRM114-Notice: Please train this message. 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 clean_dcache_guest_page() and invalidate_icache_guest_page() accept a size as an argument. But they also rely on fixmap, which can only map a single PAGE_SIZE page. With the upcoming stage-2 huge mappings for pKVM np-guests, those callbacks will get size > PAGE_SIZE. Loop the CMOs on PAGE_SIZE basis until the whole range is done. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 19c3c631708c..63968c7740c3 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -219,14 +219,30 @@ static void guest_s2_put_page(void *addr) static void clean_dcache_guest_page(void *va, size_t size) { - __clean_dcache_guest_page(hyp_fixmap_map(__hyp_pa(va)), size); - hyp_fixmap_unmap(); + if (WARN_ON(!PAGE_ALIGNED(size))) + return; + + while (size) { + __clean_dcache_guest_page(hyp_fixmap_map(__hyp_pa(va)), + PAGE_SIZE); + hyp_fixmap_unmap(); + va += PAGE_SIZE; + size -= PAGE_SIZE; + } } static void invalidate_icache_guest_page(void *va, size_t size) { - __invalidate_icache_guest_page(hyp_fixmap_map(__hyp_pa(va)), size); - hyp_fixmap_unmap(); + if (WARN_ON(!PAGE_ALIGNED(size))) + return; + + while (size) { + __invalidate_icache_guest_page(hyp_fixmap_map(__hyp_pa(va)), + PAGE_SIZE); + hyp_fixmap_unmap(); + va += PAGE_SIZE; + size -= PAGE_SIZE; + } } int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd) From patchwork Thu Mar 6 11:00:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004235 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 CA563C282EC for ; Thu, 6 Mar 2025 11:05:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=7Nk4OPygl6hlYnOAq4z2AVFwBU0df555iSROa6vHa3A=; b=gCX0CJDIj7HrlaM0G1yY+pqxgo t7mvwG0wIRJsfhaTXmSUXAnfvz5ZlHKbxU5I6uTtX7zGROE0M6AMfoF67goNo+thrVxi2Y+CaMSPS TDPEyfHnd06+0o7yqnLIIdF8SQnnUrIyqPFRk68nfF1dW/T6dCRCTG2GCyMpVCeujDS8+AaziZrPd Wv9oyu2658KEelpxHeacYs82LDSegEjxi/uPnztRB547XF6CR1xoxM3GbophhJ2HM7ZXzSz7fN1cV OE1iZSaeqtwd11TrUgkfsoITekK5fLBJC2bIZRCxtS5ZhpORdz2q/COKGGt+0VZGHVbPBJK/dm3L5 M97h1PPA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tq92s-0000000AjJu-2r5i; Thu, 06 Mar 2025 11:05:42 +0000 Received: from mail-wm1-x349.google.com ([2a00:1450:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8yB-0000000AiWO-0aBX for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:00:52 +0000 Received: by mail-wm1-x349.google.com with SMTP id 5b1f17b1804b1-43bd8fd03a2so2270935e9.3 for ; Thu, 06 Mar 2025 03:00:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258849; x=1741863649; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=7Nk4OPygl6hlYnOAq4z2AVFwBU0df555iSROa6vHa3A=; b=wGUnpzXaQ+sE8+rI0sqjDz5cnGD3Zehyfl4xEico3LndxwE39pRc5ob9x6Xt9wclYA bzVuJO0Bd2BKOSxf4EQGdFQJB0YgsnwOOGr5mqiwGMZazdBNrbFkSsw9HIVe4XSvj4hp jZiZ10K/0mRPwyNZGKGIvFFK6N5zHi7LyMUblF7UCGI9Zt6Dly6jxA2L/F9rz9a7xD6e B8yQ0JrjrDFQMjrO1L+4OGsoQR9nYw1dKIqNUDH0Lmf/vjP+OSltEekyRXIxIO27z3WH pN6D5sBMkiB9PJ2/FDNR4qbJufQnzwp3VI+lRZ6jFxgzh8cOcx8K65zf7mF8yXPROS5e a5sA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258849; x=1741863649; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7Nk4OPygl6hlYnOAq4z2AVFwBU0df555iSROa6vHa3A=; b=SqQV1ogVNfbFIIchHEzISQ8sABr2JoxuFEMUqD+ZnFAobJz6YsDNI7MUfoJoe7S/s4 cow2Vo80Y8LKbuTS6kxjrJEUOuwi2nZzinkRaUBvjPV43rZo8gZRX8O9wZdEgh+d3IAj vMKQVu1eUps0nm8Qaui9c8FWoa7/hlyDpwvYBXhO3HN6rae1RUEuxmtXVjwx0fGC4Ze+ 6euIwvbXlLUzErjAkjjANx0oG5PuRdWl9yQwoLh3VJw6EcYRDIHdM/0MmFrAxApakM5j MDtd3NBSSZQ3gDO0nseTkIofTyhI1rZnW4wb+401iFismFmVBJZg0g0HuhlHsxKHZSFb tAow== X-Forwarded-Encrypted: i=1; AJvYcCVGr84akZtAI5J7otsx3qR/hhpTc8Yql9z5xyhRyawna1LkjLnQs8iS7ZKX5WmnunNa0VbNZtOe7xy8zmzuRsix@lists.infradead.org X-Gm-Message-State: AOJu0Yyydn1J+gsv1YVc6Wdpj6ejC5KxKIkz3dRJi3vcr5j2zXaft8FW IXUNRtNfFHFMnKv2LfiGDhIwMsStsK58yaFAKHoI9cDwMFElVfCjw8PitjAP+WqoYALiy7EJO1h aSB5g2H6FnQU4Ml8Raw== X-Google-Smtp-Source: AGHT+IHG431C9Dkqi/qIYLv2PsF4AG9wTnpdTRpS5AhCVpzGRU9pbxvoEXa2dp5chGFByPGXrjbUxl1WoPU70v1o X-Received: from wmbfj12.prod.google.com ([2002:a05:600c:c8c:b0:43b:cdf0:8c03]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1988:b0:439:a1c7:7b2d with SMTP id 5b1f17b1804b1-43bd29272a3mr53453075e9.4.1741258849608; Thu, 06 Mar 2025 03:00:49 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:31 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-3-vdonnefort@google.com> Subject: [PATCH v2 2/9] KVM: arm64: Add a range to __pkvm_host_share_guest() From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030051_181596_FFDD0A64 X-CRM114-Status: GOOD ( 17.29 ) 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 In preparation for supporting stage-2 huge mappings for np-guest. Add a nr_pages argument to the __pkvm_host_share_guest hypercall. This range supports only two values: 1 or PMD_SIZE / PAGE_SIZE (that is 512 on a 4K-pages system). Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 978f38c386ee..1abbab5e2ff8 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -39,7 +39,7 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages); int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages); int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages); int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages); -int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, +int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot); int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm); int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 2c37680d954c..e71601746935 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -249,7 +249,8 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(u64, pfn, host_ctxt, 1); DECLARE_REG(u64, gfn, host_ctxt, 2); - DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3); + DECLARE_REG(u64, nr_pages, host_ctxt, 3); + DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4); struct pkvm_hyp_vcpu *hyp_vcpu; int ret = -EINVAL; @@ -264,7 +265,7 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt) if (ret) goto out; - ret = __pkvm_host_share_guest(pfn, gfn, hyp_vcpu, prot); + ret = __pkvm_host_share_guest(pfn, gfn, nr_pages, hyp_vcpu, prot); out: cpu_reg(host_ctxt, 1) = ret; } diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 63968c7740c3..7e3a249149a0 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -60,6 +60,9 @@ static void hyp_unlock_component(void) hyp_spin_unlock(&pkvm_pgd_lock); } +#define for_each_hyp_page(start, size, page) \ + for (page = hyp_phys_to_page(start); page < hyp_phys_to_page((start) + (size)); page++) + static void *host_s2_zalloc_pages_exact(size_t size) { void *addr = hyp_alloc_pages(&host_s2_pool, get_order(size)); @@ -509,10 +512,25 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size, static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state) { - phys_addr_t end = addr + size; + struct hyp_page *page; - for (; addr < end; addr += PAGE_SIZE) - hyp_phys_to_page(addr)->host_state = state; + for_each_hyp_page(addr, size, page) + page->host_state = state; +} + +static void __host_update_share_guest_count(u64 phys, u64 size, bool inc) +{ + struct hyp_page *page; + + for_each_hyp_page(phys, size, page) { + if (inc) { + WARN_ON(page->host_share_guest_count++ == U32_MAX); + } else { + WARN_ON(!page->host_share_guest_count--); + if (!page->host_share_guest_count) + page->host_state = PKVM_PAGE_OWNED; + } + } } int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) @@ -627,16 +645,16 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size, static int __host_check_page_state_range(u64 addr, u64 size, enum pkvm_page_state state) { - u64 end = addr + size; + struct hyp_page *page; int ret; - ret = check_range_allowed_memory(addr, end); + ret = check_range_allowed_memory(addr, addr + size); if (ret) return ret; hyp_assert_lock_held(&host_mmu.lock); - for (; addr < end; addr += PAGE_SIZE) { - if (hyp_phys_to_page(addr)->host_state != state) + for_each_hyp_page(addr, size, page) { + if (page->host_state != state) return -EPERM; } @@ -686,10 +704,9 @@ static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr) return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte)); } -static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr, +static int __guest_check_page_state_range(struct pkvm_hyp_vm *vm, u64 addr, u64 size, enum pkvm_page_state state) { - struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); struct check_walk_data d = { .desired = state, .get_page_state = guest_get_page_state, @@ -896,49 +913,83 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages) return ret; } -int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, +static int __guest_check_transition_size(u64 phys, u64 ipa, u64 nr_pages, u64 *size) +{ + if (nr_pages == 1) { + *size = PAGE_SIZE; + return 0; + } + + /* We solely support PMD_SIZE huge-pages */ + if (nr_pages != (1 << (PMD_SHIFT - PAGE_SHIFT))) + return -EINVAL; + + if (!IS_ALIGNED(phys | ipa, PMD_SIZE)) + return -EINVAL; + + *size = PMD_SIZE; + return 0; +} + +int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot) { struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); u64 phys = hyp_pfn_to_phys(pfn); u64 ipa = hyp_pfn_to_phys(gfn); + enum pkvm_page_state state; struct hyp_page *page; + u64 size; int ret; if (prot & ~KVM_PGTABLE_PROT_RWX) return -EINVAL; - ret = check_range_allowed_memory(phys, phys + PAGE_SIZE); + ret = __guest_check_transition_size(phys, ipa, nr_pages, &size); + if (ret) + return ret; + + ret = check_range_allowed_memory(phys, phys + size); if (ret) return ret; host_lock_component(); guest_lock_component(vm); - ret = __guest_check_page_state_range(vcpu, ipa, PAGE_SIZE, PKVM_NOPAGE); + ret = __guest_check_page_state_range(vm, ipa, size, PKVM_NOPAGE); if (ret) goto unlock; - page = hyp_phys_to_page(phys); - switch (page->host_state) { + state = hyp_phys_to_page(phys)->host_state; + for_each_hyp_page(phys, size, page) { + if (page->host_state != state) { + ret = -EPERM; + goto unlock; + } + } + + switch (state) { case PKVM_PAGE_OWNED: - WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OWNED)); + WARN_ON(__host_set_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED)); break; case PKVM_PAGE_SHARED_OWNED: - if (page->host_share_guest_count) - break; - /* Only host to np-guest multi-sharing is tolerated */ - WARN_ON(1); - fallthrough; + for_each_hyp_page(phys, size, page) { + /* Only host to np-guest multi-sharing is tolerated */ + if (WARN_ON(!page->host_share_guest_count)) { + ret = -EPERM; + goto unlock; + } + } + break; default: ret = -EPERM; goto unlock; } - WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys, + WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, size, phys, pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED), &vcpu->vcpu.arch.pkvm_memcache, 0)); - page->host_share_guest_count++; + __host_update_share_guest_count(phys, size, true); unlock: guest_unlock_component(vm); diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 930b677eb9b0..00fd9a524bf7 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -361,7 +361,7 @@ int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, return -EINVAL; lockdep_assert_held_write(&kvm->mmu_lock); - ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, prot); + ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, 1, prot); if (ret) { /* Is the gfn already mapped due to a racing vCPU? */ if (ret == -EPERM) From patchwork Thu Mar 6 11:00:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004240 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 76765C282D1 for ; Thu, 6 Mar 2025 11:07:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=6m5bqbS5De2414rudA+6hni5oX136rUbEPTOwyZJ3oE=; b=u/orxkb5E8pP0/qVqqTkHhkoxD OMzX+R9gwJPsXawWb1zlsqT4KgHIF/lEdJ/VceEyHjC9M0/mouAFa5MnsDrqR0oSDQmAj/KISZiJO q9pw+SzZu/SJAwM5oOK/yIfuAH5LgFVP1mukP1TbTgaQjNtVTVQemnTENh7urb4pkdZJsur/nr9BK OtVeGC8Ig5lK/gewEKf6JhifjdGVBUfbCZbjnkbDDeVKz9jXWOwn1Q16madYoE4Bzh/EhHIGpA+gt M4CSPhKxXWojJy6CG+HC5WiRsk6UjtVrWu3OCc6Pb9K/ycFQpPap3th54Do/V2w768XArDQirqPhr KYH3ukLA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tq94S-0000000AjU1-1tpS; Thu, 06 Mar 2025 11:07:20 +0000 Received: from mail-wm1-x34a.google.com ([2a00:1450:4864:20::34a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8yD-0000000AiWk-0O7U for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:00:54 +0000 Received: by mail-wm1-x34a.google.com with SMTP id 5b1f17b1804b1-43bc97e6360so2241485e9.3 for ; Thu, 06 Mar 2025 03:00:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258851; x=1741863651; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=6m5bqbS5De2414rudA+6hni5oX136rUbEPTOwyZJ3oE=; b=oR124gdzAszUUqbmcg7Kh7rqdP81lJQygsSrTSq3vaZcQrQG9zGQi/SFxG9PmDxnhO aFY3RxTjtgABpLUuVhXz4X74ch7ItR1id8gebTQBrvi6BchHtcvcKRjmPiMvtSp0gAhr Yzp04VN+e4+nj4hvw0nTMNvsHlKzZFbxDaRZKS0eYbbcG46xoVEFh1L02TbHBaSOQjyz 82WjZ1pIsBlSW8Vih8t0mMhmXo5NzyHsGC2VQufNq/6jsJX90Bs5Dozo5QAZEN5FX9DT laok6PYDKRquemsDNA+GULWuQpwbZ7KnAOobNpwE0urDp5/EZeMMnE3+aV149NrqiGXW GPLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258851; x=1741863651; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6m5bqbS5De2414rudA+6hni5oX136rUbEPTOwyZJ3oE=; b=VhBUxx2olfgccaC1H2RfxPHmY5DljZZ1MDChNvDb/5t/cVcIQ+rxIQTDq0227xsGF/ BAuajpHq5IHjZZslft1YAr37BHYv7/P8xvvyWiNn/Uv6T5br7ZkrFLil0Jrvfgmlu2JQ IRjQhPpp7/yHgQ4z27j+4XX2l9DfGZEdGmFSmP1m8ldeBZwliUMiPwbVrvIjX6TVuj8B 7ATpWrr6wXuiykFPQz9PHXrZvPI3PpP3lI7V7vSv0lJ/llBggw2fEtMkyAQuj8ks0QAe jXAxX7nxYcZk/mj9CY8jbz7NpiLrp/+n5gN1GnWmi8urzpOnvzFd8M3+n7xSWcquZcWs +HKQ== X-Forwarded-Encrypted: i=1; AJvYcCXcRnovadiHhdjK0CeY6fDtYP341GTx3Zm2WNIrGe0Z7FFh1Yv7BrGLYSLpJ5RbWZSJBfPUNi7zQvNB04ub3Xa9@lists.infradead.org X-Gm-Message-State: AOJu0YyXJfKzU54MHH7GqBKm0jnbcb/he21eundytNiHEHIr21VLNVua 2ew4j/sTi7NfEih7QwR+1MoItRodptSLv/bZQfq/O89lhv4zHGC0G9+B6wnnNtt7EZvw/PWRy1x W74/tlbYyD/lNWJDSXQ== X-Google-Smtp-Source: AGHT+IGZUqYVdIQcMkVSVKvjHliXkD+ge0vVye+cOo8Dd1sDdxpdmjqRMSVgh2kbfPadmJR/0CYkDABlridM7EGM X-Received: from wmqa17.prod.google.com ([2002:a05:600c:3491:b0:43b:bf84:7e47]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1c9f:b0:43b:c0fa:f9c5 with SMTP id 5b1f17b1804b1-43bd2aed752mr44314515e9.21.1741258851559; Thu, 06 Mar 2025 03:00:51 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:32 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-4-vdonnefort@google.com> Subject: [PATCH v2 3/9] KVM: arm64: Add a range to __pkvm_host_unshare_guest() From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030053_190198_5E5C6E70 X-CRM114-Status: GOOD ( 11.91 ) 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 In preparation for supporting stage-2 huge mappings for np-guest. Add a nr_pages argument to the __pkvm_host_unshare_guest hypercall. This range supports only two values: 1 or PMD_SIZE / PAGE_SIZE (that is 512 on a 4K-pages system). Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 1abbab5e2ff8..343569e4bdeb 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -41,7 +41,7 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages); int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages); int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot); -int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm); +int __pkvm_host_unshare_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *hyp_vm); int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot); int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm); int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index e71601746935..7f22d104c1f1 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -274,6 +274,7 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); DECLARE_REG(u64, gfn, host_ctxt, 2); + DECLARE_REG(u64, nr_pages, host_ctxt, 3); struct pkvm_hyp_vm *hyp_vm; int ret = -EINVAL; @@ -284,7 +285,7 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt) if (!hyp_vm) goto out; - ret = __pkvm_host_unshare_guest(gfn, hyp_vm); + ret = __pkvm_host_unshare_guest(gfn, nr_pages, hyp_vm); put_pkvm_hyp_vm(hyp_vm); out: cpu_reg(host_ctxt, 1) = ret; diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 7e3a249149a0..7b9b112e3ebf 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -998,13 +998,12 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu return ret; } -static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa) +static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa, u64 size) { - enum pkvm_page_state state; struct hyp_page *page; kvm_pte_t pte; - u64 phys; s8 level; + u64 phys; int ret; ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level); @@ -1012,51 +1011,52 @@ static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ip return ret; if (!kvm_pte_valid(pte)) return -ENOENT; - if (level != KVM_PGTABLE_LAST_LEVEL) + if (kvm_granule_size(level) != size) return -E2BIG; - state = guest_get_page_state(pte, ipa); - if (state != PKVM_PAGE_SHARED_BORROWED) - return -EPERM; + ret = __guest_check_page_state_range(vm, ipa, size, PKVM_PAGE_SHARED_BORROWED); + if (ret) + return ret; phys = kvm_pte_to_phys(pte); - ret = check_range_allowed_memory(phys, phys + PAGE_SIZE); + ret = check_range_allowed_memory(phys, phys + size); if (WARN_ON(ret)) return ret; - page = hyp_phys_to_page(phys); - if (page->host_state != PKVM_PAGE_SHARED_OWNED) - return -EPERM; - if (WARN_ON(!page->host_share_guest_count)) - return -EINVAL; + for_each_hyp_page(phys, size, page) { + if (page->host_state != PKVM_PAGE_SHARED_OWNED) + return -EPERM; + if (WARN_ON(!page->host_share_guest_count)) + return -EINVAL; + } *__phys = phys; return 0; } -int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *vm) +int __pkvm_host_unshare_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *vm) { u64 ipa = hyp_pfn_to_phys(gfn); - struct hyp_page *page; - u64 phys; + u64 size, phys; int ret; + ret = __guest_check_transition_size(0, ipa, nr_pages, &size); + if (ret) + return ret; + host_lock_component(); guest_lock_component(vm); - ret = __check_host_shared_guest(vm, &phys, ipa); + ret = __check_host_shared_guest(vm, &phys, ipa, size); if (ret) goto unlock; - ret = kvm_pgtable_stage2_unmap(&vm->pgt, ipa, PAGE_SIZE); + ret = kvm_pgtable_stage2_unmap(&vm->pgt, ipa, size); if (ret) goto unlock; - page = hyp_phys_to_page(phys); - page->host_share_guest_count--; - if (!page->host_share_guest_count) - WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED)); + __host_update_share_guest_count(phys, size, false); unlock: guest_unlock_component(vm); @@ -1076,7 +1076,7 @@ static void assert_host_shared_guest(struct pkvm_hyp_vm *vm, u64 ipa) host_lock_component(); guest_lock_component(vm); - ret = __check_host_shared_guest(vm, &phys, ipa); + ret = __check_host_shared_guest(vm, &phys, ipa, PAGE_SIZE); guest_unlock_component(vm); host_unlock_component(); diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 00fd9a524bf7..b65fcf245fc9 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -385,7 +385,7 @@ int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size) lockdep_assert_held_write(&kvm->mmu_lock); for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) { - ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn); + ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn, 1); if (WARN_ON(ret)) break; rb_erase(&mapping->node, &pgt->pkvm_mappings); From patchwork Thu Mar 6 11:00:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004241 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 198F6C282EC for ; Thu, 6 Mar 2025 11:09:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=7SUHezARLgNy4M/thAGHMxOGZWlACt+jxmQ+nWznSE4=; b=l16zyJeNWyE/mDsLPRmtboz1AR AfLBM9GiVYvuggxKKDjqTo0NBoCPAEJY/gBh/OHt01qj2NViSaMMdq/iAL4TGWm59x2kP/T7NrIl4 EvTWgsnqelpEce2VnAw3v59Jd+nEGypFDdVvzf1ZdlOiJB/nvke7+AeyMVm+RlejDXTBa6fSzg0G8 hJpPKK/Y7my7AZAvZ/IhhN8edQunmkfMCVtQ8vuJh6XOD7WMiP8iEXHr54JR4QUoWJM9ahS5bSnwM 0ZZgxXc3H4c/qoNhsmEEVDDGt7Icc2Mt2xoVgPizuK664jqGA7zrWChHOWIJ1QngZUBca6Op7R4ez R1rIiTUw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tq961-0000000Ajdm-0ZMe; Thu, 06 Mar 2025 11:08:57 +0000 Received: from mail-wm1-x34a.google.com ([2a00:1450:4864:20::34a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8yF-0000000AiXC-1qkm for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:00:56 +0000 Received: by mail-wm1-x34a.google.com with SMTP id 5b1f17b1804b1-43943bd1409so3466585e9.3 for ; Thu, 06 Mar 2025 03:00:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258854; x=1741863654; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=7SUHezARLgNy4M/thAGHMxOGZWlACt+jxmQ+nWznSE4=; b=Fw35lkN1sskQBE3O4PT4uo4JuOSr+N359pFNSH3IN8lWq3QPxiU/yfc/K1I4QiN4LK qJNbmol5BV/EBWi4seG+lDvEoNgpD4kcJ0ua9rCeofaD8cWIqwv1tN/RPnUm10/ao0zs m4k42ivL7TenOW4LxxomipeIs2b/WfeviSqCghs31RZ4YXdBL5GpVappIMsiwt8vi6Wz Qm0LLD+fBa/nypXvrHXTTdnhWRR0WNYXusKhAnpPoHWEc7DF6ZKH1Du0JIGmLME3gsyL +JC2f6/kZkDWS8Ak20XTekzRyAApve9i5SVagJy6rUMaZhPQykVW5ACdaOSHudWuTRL0 4hhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258854; x=1741863654; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7SUHezARLgNy4M/thAGHMxOGZWlACt+jxmQ+nWznSE4=; b=jJOjD55119J+A3wsD9026A/o6rPMJq/JzfbgSneg/uYREt61GR6J+mN+6igMBi2H6d c+kLifAZQAsL5nypqOT/cGrBFUAc4FZhi5hYQZI10FBj65KPV2n4AhYKuMM02jsLy0OB fvLU06YRyq9gCfSRfP33lDBsTaVS9F3yYJeqk0Rtev+YaMwK2uS9Aqh8aNxikct/18CB pXakMlujTsqPtOwoaKIXqBqSkHEJ2Rogt9XEj04Mp/F1fgLtoXb/3xMIHGPcUrpIb+nM oKHGHpyW9W5i06/Nkrm5w1/TiZctXi9+Ii9q36+Asfg87OiXQ6XND38uxuc92t/Z/UlL 65fQ== X-Forwarded-Encrypted: i=1; AJvYcCVUO+Edhr6+l+8Sq8ruc8JzArq7iPshl9T1T1wGOu/qCrg8G78d7jyAikNSLfF8BixYNSApLYdTK+OEPkuf+3lt@lists.infradead.org X-Gm-Message-State: AOJu0YxnV4s5QPVTmNDmRM6rlofXyrN4gSfd8TExjN8ahBPCLgwIW2F+ snpZ5BmCZfPmd3J6bal1J2CLxbAlSjT47H66waMqR6+fzAs0AfNZvWL+84tRuUtqC9afMcRpt31 OgQDjSLHRFwdvcwpcvQ== X-Google-Smtp-Source: AGHT+IF6cBYpJoNeFh9z8abT4JT8Lu/iLr3ILSFRx27w0PV32EPVnLrrgtC4Mtm0Y1G3MzlzdEBEE6shWor6mMCw X-Received: from wmqb9.prod.google.com ([2002:a05:600c:4e09:b0:43b:d42e:35b9]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4fd0:b0:439:6118:c188 with SMTP id 5b1f17b1804b1-43bd2adab55mr51000745e9.19.1741258853873; Thu, 06 Mar 2025 03:00:53 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:33 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-5-vdonnefort@google.com> Subject: [PATCH v2 4/9] KVM: arm64: Add a range to __pkvm_host_wrprotect_guest() From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030055_566850_F56A8D18 X-CRM114-Status: GOOD ( 10.94 ) 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 In preparation for supporting stage-2 huge mappings for np-guest. Add a nr_pages argument to the __pkvm_host_wrprotect_guest hypercall. This range supports only two values: 1 or PMD_SIZE / PAGE_SIZE (that is 512 on a 4K-pages system). Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 343569e4bdeb..ad6131033114 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -43,8 +43,8 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu enum kvm_pgtable_prot prot); int __pkvm_host_unshare_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *hyp_vm); int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot); -int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm); int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm); +int __pkvm_host_wrprotect_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *hyp_vm); int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu); bool addr_is_memory(phys_addr_t phys); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 7f22d104c1f1..e13771a67827 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -314,6 +314,7 @@ static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt { DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); DECLARE_REG(u64, gfn, host_ctxt, 2); + DECLARE_REG(u64, nr_pages, host_ctxt, 3); struct pkvm_hyp_vm *hyp_vm; int ret = -EINVAL; @@ -324,7 +325,7 @@ static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt if (!hyp_vm) goto out; - ret = __pkvm_host_wrprotect_guest(gfn, hyp_vm); + ret = __pkvm_host_wrprotect_guest(gfn, nr_pages, hyp_vm); put_pkvm_hyp_vm(hyp_vm); out: cpu_reg(host_ctxt, 1) = ret; diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 7b9b112e3ebf..e113ece1b759 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -1065,7 +1065,7 @@ int __pkvm_host_unshare_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *vm) return ret; } -static void assert_host_shared_guest(struct pkvm_hyp_vm *vm, u64 ipa) +static void assert_host_shared_guest(struct pkvm_hyp_vm *vm, u64 ipa, u64 size) { u64 phys; int ret; @@ -1076,7 +1076,7 @@ static void assert_host_shared_guest(struct pkvm_hyp_vm *vm, u64 ipa) host_lock_component(); guest_lock_component(vm); - ret = __check_host_shared_guest(vm, &phys, ipa, PAGE_SIZE); + ret = __check_host_shared_guest(vm, &phys, ipa, size); guest_unlock_component(vm); host_unlock_component(); @@ -1096,7 +1096,7 @@ int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_ if (prot & ~KVM_PGTABLE_PROT_RWX) return -EINVAL; - assert_host_shared_guest(vm, ipa); + assert_host_shared_guest(vm, ipa, PAGE_SIZE); guest_lock_component(vm); ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0); guest_unlock_component(vm); @@ -1104,17 +1104,21 @@ int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_ return ret; } -int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm) +int __pkvm_host_wrprotect_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *vm) { - u64 ipa = hyp_pfn_to_phys(gfn); + u64 size, ipa = hyp_pfn_to_phys(gfn); int ret; if (pkvm_hyp_vm_is_protected(vm)) return -EPERM; - assert_host_shared_guest(vm, ipa); + ret = __guest_check_transition_size(0, ipa, nr_pages, &size); + if (ret) + return ret; + + assert_host_shared_guest(vm, ipa, size); guest_lock_component(vm); - ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, PAGE_SIZE); + ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, size); guest_unlock_component(vm); return ret; @@ -1128,7 +1132,7 @@ int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm * if (pkvm_hyp_vm_is_protected(vm)) return -EPERM; - assert_host_shared_guest(vm, ipa); + assert_host_shared_guest(vm, ipa, PAGE_SIZE); guest_lock_component(vm); ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, PAGE_SIZE, mkold); guest_unlock_component(vm); @@ -1144,7 +1148,7 @@ int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu) if (pkvm_hyp_vm_is_protected(vm)) return -EPERM; - assert_host_shared_guest(vm, ipa); + assert_host_shared_guest(vm, ipa, PAGE_SIZE); guest_lock_component(vm); kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0); guest_unlock_component(vm); diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index b65fcf245fc9..3ea92bb79e8c 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -404,7 +404,7 @@ int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size) lockdep_assert_held(&kvm->mmu_lock); for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) { - ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn); + ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn, 1); if (WARN_ON(ret)) break; } From patchwork Thu Mar 6 11:00:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004242 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 14055C282EC for ; Thu, 6 Mar 2025 11:10:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=nY53fsjf1Gqi90zwwkjs/Ss31wicoUxN0lBzPVMQZ48=; b=hzJsYIUS1N9TWbvmdmDYcBDLjl J/zXgVnOfBZLF8V41ZtYGpWyAmqhuxwOH/EzaMjAI87FZ9FHrTXfrMZOnl+fuzkGTVZ39x0/cyfPF p8MQYKeTR6fQd6EooX9Vqv3GrFgLT0smZVHm0W0JjAKMlnGp9p2iZKymGmonnqUBup1LbsWmi1iyc OaFQLpDhkkLKnHFH0QNz8XLuTyOEEIH/5yKsuSOAI7qcIwFt1OsLBJvPM3S9PS4aTmXeDZrJBFkz7 sZbpUlpvCYVsj75TFC02iY6VfR9NRPIRbhMYOPsHWE02IjyZduspITeP9v+Hf7pzrYA0hG4KSTnFn tciDO2AQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tq97b-0000000Ak0m-3c1R; Thu, 06 Mar 2025 11:10:35 +0000 Received: from mail-wm1-x34a.google.com ([2a00:1450:4864:20::34a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8yH-0000000AiXj-3KDs for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:00:58 +0000 Received: by mail-wm1-x34a.google.com with SMTP id 5b1f17b1804b1-43943bd1409so3466875e9.3 for ; Thu, 06 Mar 2025 03:00:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258856; x=1741863656; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=nY53fsjf1Gqi90zwwkjs/Ss31wicoUxN0lBzPVMQZ48=; b=aETTQGvAdW6LY6UoJ/Fl+cOfXb3yBOcCniC6KIsWiCNfwxdwcxUlsLFdPpxLp1jrzy 4j3IpIPks+czwgAciokvVfG6drxbuUj76gBentRYEtozxfpetiwhrXXUxJ1FmKQpGbSa tS+goc9chk/LVid4GhZm7a7gfOJfjVleQ1TtSLIGC3vE8DMOYxc90gvqswAAajKNnL4R 0Ei9Y95DfVdOzLfzYAWGfn5/L6tBz7G5HCTNuG/dEu/ijSJoF7MsqFSUIXPLnTODxfqd cqElAYkWgf8eLfexobtqockDbY2WT6b1YXf3cSTPaE9kATM2l5VxYdH7SvDo9BQDVGkt CSLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258856; x=1741863656; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nY53fsjf1Gqi90zwwkjs/Ss31wicoUxN0lBzPVMQZ48=; b=o9jiVvrJh3HEg2EKR0FgGZ2gz6axlGfxXV5GmYD6HoMmx9W/vKwCyVXNZ/u8REiqEO bPtzj52lxtPZuyQzLdfn+k2oGOs/sHHGWptwiDuntarv8+S+V/xjB6lr0o7LglmFK0YK Kojld3doGbsFwSo6xzYivCRC0uyhXuikj2i4O1U4QXeOhU8ayYnwSkJ9/i0H2p546MLb Xqqg5JOxqHqVWmBquS26oZyIlGfZyZjExjG2nFWR2fv7R9/H5dqtJBlmEsx0Et7ZZrgE ifUv6aJzZs/7NAyTAm3gTyQUUoLfKnG/obm4cY0eT8m0hFESf2cdLgI6kIkKteyTDM9m YK8A== X-Forwarded-Encrypted: i=1; AJvYcCVSXtX6j8US3g0ziTRQthWjetmaMT0OR9SGQx3oddU506G5sfU3EzdVc4rlAbMkJYy4eH1CaQeimTlRPLElwf5n@lists.infradead.org X-Gm-Message-State: AOJu0YyRjoyv1o2AIxRyAIIZJGJCCEG7lo1s31gZzB8cHZgxgbIXeXqB GVi5WAkir3M1R8zyxNbtSigNaVb2sbIBS0eioJu3QzWvM8lxwWNcyqY/C1NoI514uYI9MEiksZm py8iVrBBY78ywaZD0xA== X-Google-Smtp-Source: AGHT+IGmQeadGZM6t/fuvRDJiBZnTtGUTvo721CNjh1/3loduEsrkWUlmN6OyAD3MtikSnlm82gvqe/Rikhd5Zkg X-Received: from wmbbh11.prod.google.com ([2002:a05:600c:3d0b:b0:43b:c0cf:b8e2]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:59ae:0:b0:391:2995:5ef2 with SMTP id ffacd0b85a97d-3912995602cmr2172678f8f.37.1741258856189; Thu, 06 Mar 2025 03:00:56 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:34 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-6-vdonnefort@google.com> Subject: [PATCH v2 5/9] KVM: arm64: Add a range to __pkvm_host_test_clear_young_guest() From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030057_865671_0E34B07E X-CRM114-Status: UNSURE ( 9.99 ) X-CRM114-Notice: Please train this message. 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 In preparation for supporting stage-2 huge mappings for np-guest. Add a nr_pages argument to the __pkvm_host_test_clear_young_guest hypercall. This range supports only two values: 1 or PMD_SIZE / PAGE_SIZE (that is 512 on a 4K-pages system). Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index ad6131033114..0c88c92fc3a2 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -43,8 +43,8 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu enum kvm_pgtable_prot prot); int __pkvm_host_unshare_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *hyp_vm); int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot); -int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm); int __pkvm_host_wrprotect_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *hyp_vm); +int __pkvm_host_test_clear_young_guest(u64 gfn, u64 nr_pages, bool mkold, struct pkvm_hyp_vm *vm); int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu); bool addr_is_memory(phys_addr_t phys); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index e13771a67827..a6353aacc36c 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -335,7 +335,8 @@ static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *ho { DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); DECLARE_REG(u64, gfn, host_ctxt, 2); - DECLARE_REG(bool, mkold, host_ctxt, 3); + DECLARE_REG(u64, nr_pages, host_ctxt, 3); + DECLARE_REG(bool, mkold, host_ctxt, 4); struct pkvm_hyp_vm *hyp_vm; int ret = -EINVAL; @@ -346,7 +347,7 @@ static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *ho if (!hyp_vm) goto out; - ret = __pkvm_host_test_clear_young_guest(gfn, mkold, hyp_vm); + ret = __pkvm_host_test_clear_young_guest(gfn, nr_pages, mkold, hyp_vm); put_pkvm_hyp_vm(hyp_vm); out: cpu_reg(host_ctxt, 1) = ret; diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index e113ece1b759..61bf26a911e6 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -1124,17 +1124,21 @@ int __pkvm_host_wrprotect_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *vm) return ret; } -int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm) +int __pkvm_host_test_clear_young_guest(u64 gfn, u64 nr_pages, bool mkold, struct pkvm_hyp_vm *vm) { - u64 ipa = hyp_pfn_to_phys(gfn); + u64 size, ipa = hyp_pfn_to_phys(gfn); int ret; if (pkvm_hyp_vm_is_protected(vm)) return -EPERM; - assert_host_shared_guest(vm, ipa, PAGE_SIZE); + ret = __guest_check_transition_size(0, ipa, nr_pages, &size); + if (ret) + return ret; + + assert_host_shared_guest(vm, ipa, size); guest_lock_component(vm); - ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, PAGE_SIZE, mkold); + ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, size, mkold); guest_unlock_component(vm); return ret; diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 3ea92bb79e8c..2eb1cc30124e 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -434,7 +434,7 @@ bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 lockdep_assert_held(&kvm->mmu_lock); for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn, - mkold); + 1, mkold); return young; } From patchwork Thu Mar 6 11:00:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004398 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 46BB9C282EC for ; Thu, 6 Mar 2025 12:19:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=KTPitoEhlDo5P7Fhw0/so0kkZd/7LTKjAqNYGdJzP/Q=; b=2iSL8HWRarYIyMDZtzVF7HiyPM lBH/M0oCmlOQa6RMQSQbqsUr03z7Dxt083s+PhVUm1eaOJSxJ1JeSf1GNq3B4yQ85efzX0eFWIZPe UpqJvs1XBEUnW4TLiodfwGMcFCIq8ZV2yeYyrZqJsnCckIju1fT4qMZSss1hzW4tnwFvd1K8l9XAq 1cD3gjeGCSS8k1JAW8Gl7RM0S9kbwwOUX3DOhDzc41p4j+1GFncKONIZDz8NGLKMHQNflAvAEW5bP o8whphjVuySXhUqfIqMOfdXsLxAntUobhNvWJeicsWIPSiGXD7yJGsW6WYm9lzqPVV/BqLs7deznu cuMwOJAQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tqABk-0000000Ataz-3MNh; Thu, 06 Mar 2025 12:18:56 +0000 Received: from mail-wr1-x44a.google.com ([2a00:1450:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8yK-0000000AiY7-2JLN for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:01:01 +0000 Received: by mail-wr1-x44a.google.com with SMTP id ffacd0b85a97d-390fd681712so255397f8f.3 for ; Thu, 06 Mar 2025 03:00:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258858; x=1741863658; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=KTPitoEhlDo5P7Fhw0/so0kkZd/7LTKjAqNYGdJzP/Q=; b=bpwgbUGqyd2O85Fi/uDLF4A4l3U5bAAx1dzmq6sJlEXKffO2q+4f3TkmxcwmpcIZUS lHZYGbs1UY4ZxSe6PxF/d1DZtoanD+1lN8TAKvW2ALGmnt2s3JBxWkOTOVI3L3XUw24h m1Q9Z4naFAgTMCAY4gfHs1/b6PfHeS6HzLfuiHJ/R8kfrV+O/wvD3ct4m5ijae1twopM TfHhASvhwT4BUKjW5WKoDZU7Dm8KMMRh560p3jlpJElhuoTE258orzO8Rq1a2m0ZC0Qo o30CFjW5QveeiYRkMHeD6hXgyxQyBW+otK9GUFc3kV2F+QQYnC3IkXs3ymWm7KTK11ER RZlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258858; x=1741863658; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=KTPitoEhlDo5P7Fhw0/so0kkZd/7LTKjAqNYGdJzP/Q=; b=pT/BEdAhj893gBOlUEgp5L3Xrn/Jt/4ydT7fNWpmzCdpKDuFQOuv4BG2XzxLZA1YED gUTDQZRQCH1KD9AUDwEzWXxhEvRMQhVzdn5sPdoGdEOpaN6K6Z+gzZYegL4+gxvrivFG CI6qf8CdNXqNj3YJ+ETVoAlJ8JDV5W9I2By37FLd4Ne3bsZhOPHf8eQg/u4dLjd0l7HP uYTZ5cxokF1IMYv6Qruxo+/luW/JWW3bCIeOhrgL4HLfimDOnjGAqGKPYwf54vK802/F vw3NBkg/3fA7+HF/B9Vx+/qG3G4MXlMLjO5Txwed1p+0/WgjKbPyY6DeFphX1H+4xsW0 SAWg== X-Forwarded-Encrypted: i=1; AJvYcCVEC68d+7vFGy2bLPt+/Gj52aECXvi7ELeyfQZ6Sp3tZy3jJtcPjKO1dyF9eqbvkHJ18PqC3LSykTcRYbXJdeCZ@lists.infradead.org X-Gm-Message-State: AOJu0YwvAST1abVTuWopRa3biYHO2sjT5uWTl7qClDCcfp0j/RRwNxwS sqpp8ofwrQQKlLxv0Y1/PLH1w7YZ2oFCiBWYGsrwK4ajm7+hoIhD0gkKcpBuzsm5MSC6MlBUBE5 8hbIThZlGW2XVGv9HPA== X-Google-Smtp-Source: AGHT+IEQXtW78/QgWwghNEF6Ze5xCQXvF/c8p86Yy8JUgqzhZp0+q+YljOi0jNJBtHSuvG1B9ZTMgCSQ9MCrQG8P X-Received: from wmpz20.prod.google.com ([2002:a05:600c:a14:b0:43b:d6ca:6dd3]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:1fa9:b0:391:c42:dbc with SMTP id ffacd0b85a97d-3911f72608amr6177818f8f.8.1741258858144; Thu, 06 Mar 2025 03:00:58 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:35 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-7-vdonnefort@google.com> Subject: [PATCH v2 6/9] KVM: arm64: Convert pkvm_mappings to interval tree From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030100_596991_2BC3C59A X-CRM114-Status: GOOD ( 16.11 ) 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 From: Quentin Perret In preparation for supporting stage-2 huge mappings for np-guest, let's convert pgt.pkvm_mappings to an interval tree. No functional change intended. Suggested-by: Vincent Donnefort Signed-off-by: Quentin Perret Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index 6b9d274052c7..1b43bcd2a679 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -413,7 +413,7 @@ static inline bool kvm_pgtable_walk_lock_held(void) */ struct kvm_pgtable { union { - struct rb_root pkvm_mappings; + struct rb_root_cached pkvm_mappings; struct { u32 ia_bits; s8 start_level; diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h index eb65f12e81d9..f0d52efb858e 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -166,6 +166,7 @@ struct pkvm_mapping { struct rb_node node; u64 gfn; u64 pfn; + u64 __subtree_last; /* Internal member for interval tree */ }; int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 2eb1cc30124e..da637c565ac9 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -270,80 +271,63 @@ static int __init finalize_pkvm(void) } device_initcall_sync(finalize_pkvm); -static int cmp_mappings(struct rb_node *node, const struct rb_node *parent) +static u64 __pkvm_mapping_start(struct pkvm_mapping *m) { - struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node); - struct pkvm_mapping *b = rb_entry(parent, struct pkvm_mapping, node); - - if (a->gfn < b->gfn) - return -1; - if (a->gfn > b->gfn) - return 1; - return 0; + return m->gfn * PAGE_SIZE; } -static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn) +static u64 __pkvm_mapping_end(struct pkvm_mapping *m) { - struct rb_node *node = root->rb_node, *prev = NULL; - struct pkvm_mapping *mapping; - - while (node) { - mapping = rb_entry(node, struct pkvm_mapping, node); - if (mapping->gfn == gfn) - return node; - prev = node; - node = (gfn < mapping->gfn) ? node->rb_left : node->rb_right; - } - - return prev; + return (m->gfn + 1) * PAGE_SIZE - 1; } -/* - * __tmp is updated to rb_next(__tmp) *before* entering the body of the loop to allow freeing - * of __map inline. - */ +INTERVAL_TREE_DEFINE(struct pkvm_mapping, node, u64, __subtree_last, + __pkvm_mapping_start, __pkvm_mapping_end, static, + pkvm_mapping); + #define for_each_mapping_in_range_safe(__pgt, __start, __end, __map) \ - for (struct rb_node *__tmp = find_first_mapping_node(&(__pgt)->pkvm_mappings, \ - ((__start) >> PAGE_SHIFT)); \ + for (struct pkvm_mapping *__tmp = pkvm_mapping_iter_first(&(__pgt)->pkvm_mappings, \ + __start, __end - 1); \ __tmp && ({ \ - __map = rb_entry(__tmp, struct pkvm_mapping, node); \ - __tmp = rb_next(__tmp); \ + __map = __tmp; \ + __tmp = pkvm_mapping_iter_next(__map, __start, __end - 1); \ true; \ }); \ - ) \ - if (__map->gfn < ((__start) >> PAGE_SHIFT)) \ - continue; \ - else if (__map->gfn >= ((__end) >> PAGE_SHIFT)) \ - break; \ - else + ) int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops) { - pgt->pkvm_mappings = RB_ROOT; + pgt->pkvm_mappings = RB_ROOT_CACHED; pgt->mmu = mmu; return 0; } -void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) +static int __pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 start, u64 end) { struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu); pkvm_handle_t handle = kvm->arch.pkvm.handle; struct pkvm_mapping *mapping; - struct rb_node *node; + int ret; if (!handle) - return; + return 0; - node = rb_first(&pgt->pkvm_mappings); - while (node) { - mapping = rb_entry(node, struct pkvm_mapping, node); - kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn); - node = rb_next(node); - rb_erase(&mapping->node, &pgt->pkvm_mappings); + for_each_mapping_in_range_safe(pgt, start, end, mapping) { + ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn, 1); + if (WARN_ON(ret)) + return ret; + pkvm_mapping_remove(mapping, &pgt->pkvm_mappings); kfree(mapping); } + + return 0; +} + +void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) +{ + __pkvm_pgtable_stage2_unmap(pgt, 0, ~(0ULL)); } int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, @@ -371,28 +355,16 @@ int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, swap(mapping, cache->mapping); mapping->gfn = gfn; mapping->pfn = pfn; - WARN_ON(rb_find_add(&mapping->node, &pgt->pkvm_mappings, cmp_mappings)); + pkvm_mapping_insert(mapping, &pgt->pkvm_mappings); return ret; } int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size) { - struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu); - pkvm_handle_t handle = kvm->arch.pkvm.handle; - struct pkvm_mapping *mapping; - int ret = 0; + lockdep_assert_held_write(&kvm_s2_mmu_to_kvm(pgt->mmu)->mmu_lock); - lockdep_assert_held_write(&kvm->mmu_lock); - for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) { - ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn, 1); - if (WARN_ON(ret)) - break; - rb_erase(&mapping->node, &pgt->pkvm_mappings); - kfree(mapping); - } - - return ret; + return __pkvm_pgtable_stage2_unmap(pgt, addr, addr + size); } int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size) From patchwork Thu Mar 6 11:00:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004247 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 AFAEBC28B22 for ; Thu, 6 Mar 2025 11:13:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=qXik8AjbYyPYjDFsjvp2RmgmvxUrFId1oBHnRgszILo=; b=b1aHCh/ViCHz+l6rvP2knafJ+6 vn/OpTaDVoEEDnEc6W0ukiqGNkCcstb7MzzgkY1ie8oYPD0f7l2hgVmNqxQfI1feQfQNs3A3BZL8x K2rdjBiB15tJqqD0b3fY9K9qOED/mf/yh2YRGghX1b1+S0p7kHVn+RIAD0Nc7iYS60rVP4G+oLhX1 Ve9ZkkqOkY7WoCqE+pWxwY+OXGI+K0U+6QmqZDyEyFyEE7vU9j6fOT/km9XMW9yTTvll/EVvw46T3 G9x0eZXu69afra5B8lnzeWnSGF0niWFS77MCo4dcH7TOtkU3qLJ0DAKWFjRwRrD8SeiWJYicJZw+D y3PIQXJA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tq9Aj-0000000AkO7-3ZVZ; Thu, 06 Mar 2025 11:13:49 +0000 Received: from mail-wm1-x349.google.com ([2a00:1450:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8yM-0000000AiZD-0Cuc for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:01:04 +0000 Received: by mail-wm1-x349.google.com with SMTP id 5b1f17b1804b1-43bd0586a73so5013985e9.2 for ; Thu, 06 Mar 2025 03:01:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258860; x=1741863660; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=qXik8AjbYyPYjDFsjvp2RmgmvxUrFId1oBHnRgszILo=; b=mMyzUe+l2Oi2vVxt/+FP+dblAIvLB435tn5fY9s0gArzxYRwKJwI6EdFa7A4DaG6bK hU+qM4OMYOkDx8/EXTs+mP4cEdr4LitzfYMAVj8ZjE7XL2HPdPiu7Q43Td0huDd9EcV3 nujpvHr9mQJYHnwTjtNU9TK1AW9xjAtg588lo5CjCfh7kRTxPmCNv5PTwkNjRW3XLlK3 8GSSgbjDG2KiNYccvcgxHx90LBJul1Ng4G9iqbnbTmDbG1KI0/CgwnKTfxa1QJHq8OAN v7LUwzTH3cGPGPVIyqjsPay1hVAVkPtpNkY4ENSKx4CH6FrE2OTbtcuMPmSQ7PnlxAx7 5exA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258860; x=1741863660; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=qXik8AjbYyPYjDFsjvp2RmgmvxUrFId1oBHnRgszILo=; b=mHrNhT6eCS+OQguNAMKvrjmBy3NSlZMvFb5w2vy0r0J4xJx5zaCY3R6PooW1ZGln3g nBysIslp5sewSwlV9PUR5fJS9ZOq1fnTcwX1DEqi7/KwiV97bWXzBIIcwCoa+EvtVr+0 ExuXl7zovtOubtS70f6LyODqTRNgXyudJQram+8KQC4tcFZJASHfJBzIpLXRI/EaWivt deugvv6MM89DSNA9QBkV14eeSrX3KpxjLy3w92/agmyqBHbreJ1eurj2tXIY6q3sOyow ufEej/Ae/uYb9IgS/vqecdDojYWGvIHDtNHXkwIwFdPhzAT/vVTZwGt0LpUIquQW/vaN B8pQ== X-Forwarded-Encrypted: i=1; AJvYcCXt1zUa5aCO+xcaLhBVs4VTuvIaQXHfr0KEIA/ZAk1xK0Dqs79W0J+Thp4blVfNSNqN37gEZoiXwZJ+nLh/zewf@lists.infradead.org X-Gm-Message-State: AOJu0YxF2M5W5mYBH/V0rDXeee7ULoPIpOK87qOJqIGLmseIX/N78E8v CUYReF2A9RWrVZWqwD9rnZwh4waYY415LmRzbWzVhACMTJlE1sVO/hC2ruaGt2NeEerfRqvpgdN e5pEpy6uY3jAZ2AOjWQ== X-Google-Smtp-Source: AGHT+IG1zpmCoE47NgJOQQ1JcAF2Bl3oBRwYgO4WaRdecPq4Be2Q4d+PX+LTxNRaXoONJrSQGsIXYlKSmDSqbhOe X-Received: from wmbfp6.prod.google.com ([2002:a05:600c:6986:b0:43b:cf2d:8027]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:198f:b0:439:9ee1:86bf with SMTP id 5b1f17b1804b1-43bd294309bmr67065855e9.7.1741258860152; Thu, 06 Mar 2025 03:01:00 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:36 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-8-vdonnefort@google.com> Subject: [PATCH v2 7/9] KVM: arm64: Add a range to pkvm_mappings From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030102_111133_E81A8C8F X-CRM114-Status: GOOD ( 13.40 ) 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 From: Quentin Perret In preparation for supporting stage-2 huge mappings for np-guest, add a nr_pages member for pkvm_mappings to allow EL1 to track the size of the stage-2 mapping. Signed-off-by: Quentin Perret Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h index f0d52efb858e..0e944a754b96 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -166,6 +166,7 @@ struct pkvm_mapping { struct rb_node node; u64 gfn; u64 pfn; + u64 nr_pages; u64 __subtree_last; /* Internal member for interval tree */ }; diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index da637c565ac9..9c9833f27fe3 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -278,7 +278,7 @@ static u64 __pkvm_mapping_start(struct pkvm_mapping *m) static u64 __pkvm_mapping_end(struct pkvm_mapping *m) { - return (m->gfn + 1) * PAGE_SIZE - 1; + return (m->gfn + m->nr_pages) * PAGE_SIZE - 1; } INTERVAL_TREE_DEFINE(struct pkvm_mapping, node, u64, __subtree_last, @@ -315,7 +315,8 @@ static int __pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 start, u64 e return 0; for_each_mapping_in_range_safe(pgt, start, end, mapping) { - ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn, 1); + ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn, + mapping->nr_pages); if (WARN_ON(ret)) return ret; pkvm_mapping_remove(mapping, &pgt->pkvm_mappings); @@ -345,16 +346,32 @@ int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, return -EINVAL; lockdep_assert_held_write(&kvm->mmu_lock); - ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, 1, prot); - if (ret) { - /* Is the gfn already mapped due to a racing vCPU? */ - if (ret == -EPERM) + + /* + * Calling stage2_map() on top of existing mappings is either happening because of a race + * with another vCPU, or because we're changing between page and block mappings. As per + * user_mem_abort(), same-size permission faults are handled in the relax_perms() path. + */ + mapping = pkvm_mapping_iter_first(&pgt->pkvm_mappings, addr, addr + size - 1); + if (mapping) { + if (size == (mapping->nr_pages * PAGE_SIZE)) return -EAGAIN; + + /* Remove _any_ pkvm_mapping overlapping with the range, bigger or smaller. */ + ret = __pkvm_pgtable_stage2_unmap(pgt, addr, addr + size); + if (ret) + return ret; + mapping = NULL; } + ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, size / PAGE_SIZE, prot); + if (WARN_ON(ret)) + return ret; + swap(mapping, cache->mapping); mapping->gfn = gfn; mapping->pfn = pfn; + mapping->nr_pages = size / PAGE_SIZE; pkvm_mapping_insert(mapping, &pgt->pkvm_mappings); return ret; @@ -376,7 +393,8 @@ int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size) lockdep_assert_held(&kvm->mmu_lock); for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) { - ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn, 1); + ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn, + mapping->nr_pages); if (WARN_ON(ret)) break; } @@ -391,7 +409,8 @@ int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size) lockdep_assert_held(&kvm->mmu_lock); for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) - __clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), PAGE_SIZE); + __clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), + PAGE_SIZE * mapping->nr_pages); return 0; } @@ -406,7 +425,7 @@ bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 lockdep_assert_held(&kvm->mmu_lock); for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn, - 1, mkold); + mapping->nr_pages, mkold); return young; } From patchwork Thu Mar 6 11:00:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004248 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 BDFE4C282D1 for ; Thu, 6 Mar 2025 11:15:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=azWhDzZbtoxtjhQWlpXB32XSGr+Msg3K3f2k/5PFntI=; b=3lONO35D1bUk679BHuptCoRvrv lzo3zktPBGLSF9SqOOn5yxohQibpdlP5AE6VMSvU46JbQjvD7ihn0kVptcqwEl3kplQZ8q4kHUMhP vhoIMiUAMd/t7XyI35V0S8mw7gvpVmDtd5ngM2RWCUz5EKhNXZLM16IDOYUnJUIrz/dwP5LKLP8vS t3+iMuou565/F/AR34bOaYcr8fio0kCmxqcYNHoRmOAnnxP8NIfIMul2ushzWXvINpoi+3/7WxnGz fyxtRzFgPg4qmmLNBUQ4pxbsBJJN9mzmZ7d7CB+IVkmlMCyMKDZrq2kGzG8ADOcVq0Ua0E4L5aIUj tvK6G4UQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tq9CJ-0000000AkW4-2E4j; Thu, 06 Mar 2025 11:15:27 +0000 Received: from mail-wm1-x34a.google.com ([2a00:1450:4864:20::34a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8yO-0000000Aib7-0Seq for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:01:05 +0000 Received: by mail-wm1-x34a.google.com with SMTP id 5b1f17b1804b1-4393e89e910so2294805e9.0 for ; Thu, 06 Mar 2025 03:01:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258862; x=1741863662; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=azWhDzZbtoxtjhQWlpXB32XSGr+Msg3K3f2k/5PFntI=; b=Lw/P58vb0FYEFB7JgDf8Ag65ivkWljANDj7dBsjmczvF8qqhpDImA2MpUOWAhgWuaq HJMVbkaEVT/lpO+1H+eAgsrfrlsbeIyv9h7cOuciv2dhO5LhswY+16iNLv3w0V58YfLy ojVSGce/0S/0/ztKt3K4c8SKv9GdMD/RJMLVeVkRsVMi65hBkdFRLtb64dZVVGPa8Qrz 8IrrIqKgAsE1JuS6IWt1VRjkKY9k/XL5SauUcE76TalT//gz1elMAXYO9stVswamENQl qtdjCNSbwnTZcsIo/eiwfjcQMVkCujTSXaDjaEhOXr/xwqbIiaCubM8uHPMvU06NRy+u Rcfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258862; x=1741863662; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=azWhDzZbtoxtjhQWlpXB32XSGr+Msg3K3f2k/5PFntI=; b=lQrDwnM+IkbVbq7DzAEeOZsBLWP3U+gZFOtttVp7R/FxnHzNuEx6p7rPXrSqUj9nMP j0AKqKe8SEyET2YEYsGmavpK0k6lUmp50CDfX7FZT+XZVYtMrSCbiZkO0IAPz2OegqY+ 2hMsgXhrxcS2dH5wzy8NdgjG76vhyvbsWqI12nPkr7IFC2aOd9zKw7DOoQBp8X0mSEzV c73RCJzhkx8sMOMmO7RQulaklpR7F14O9m3FG55S1LvIFbQa7cezqiE7sggcdzdBnNpF J8myb7LFpPHkPaMgeX/qmtbo941ljBBCtuVz7RSYGRwNSa4+uTVM5/Zeze1eGeDdRwuC BD7w== X-Forwarded-Encrypted: i=1; AJvYcCXTmeAOK/LXmqROsHjG0owNHwCQz3UhrnVj9Wv8s45G85AQUL2bKo58xAubL5TTA2oA5bSZIr6JMCP94TGczgKm@lists.infradead.org X-Gm-Message-State: AOJu0YydolPmUY91AGpy7ARXSBhTD032ikLh6EE7IHIVlL73Y1x/7FIF 6edmL7+YJkS1ISgahAO/u9StwIm16JNE54MzBNnmhHb2J0jgk6sCIQMIai2yiGYVk0X5G0qSDl1 x87cp+wbZPAKsuZDi0Q== X-Google-Smtp-Source: AGHT+IHaLhB8g0ea9IzCe71YUfuaamK20WvX24Cg501MmU1HL29IV3XbEohWkl/ds2ZX3TqbOYoDRDMXlJjEcXa3 X-Received: from wmbeb18.prod.google.com ([2002:a05:600c:6792:b0:43b:c205:3a80]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4450:b0:439:98ca:e390 with SMTP id 5b1f17b1804b1-43bd2af45eamr50778475e9.27.1741258862389; Thu, 06 Mar 2025 03:01:02 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:37 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-9-vdonnefort@google.com> Subject: [PATCH v2 8/9] KVM: arm64: Stage-2 huge mappings for np-guests From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030104_164508_03B7CF2A X-CRM114-Status: UNSURE ( 9.57 ) X-CRM114-Notice: Please train this message. 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 Now np-guests hypercalls with range are supported, we can let the hypervisor to install block mappings whenever the Stage-1 allows it, that is when backed by either Hugetlbfs or THPs. The size of those block mappings is limited to PMD_SIZE. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 61bf26a911e6..b7a995a1d70b 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -167,7 +167,7 @@ int kvm_host_prepare_stage2(void *pgt_pool_base) static bool guest_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot) { - return true; + return false; } static void *guest_s2_zalloc_pages_exact(size_t size) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 1f55b0c7b11d..3143f3b52c93 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1525,7 +1525,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, * logging_active is guaranteed to never be true for VM_PFNMAP * memslots. */ - if (logging_active || is_protected_kvm_enabled()) { + if (logging_active) { force_pte = true; vma_shift = PAGE_SHIFT; } else { @@ -1535,7 +1535,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, switch (vma_shift) { #ifndef __PAGETABLE_PMD_FOLDED case PUD_SHIFT: - if (fault_supports_stage2_huge_mapping(memslot, hva, PUD_SIZE)) + if (is_protected_kvm_enabled() || + fault_supports_stage2_huge_mapping(memslot, hva, PUD_SIZE)) break; fallthrough; #endif diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 9c9833f27fe3..b40bcdb1814d 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -342,7 +342,7 @@ int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 pfn = phys >> PAGE_SHIFT; int ret; - if (size != PAGE_SIZE) + if (size != PAGE_SIZE && size != PMD_SIZE) return -EINVAL; lockdep_assert_held_write(&kvm->mmu_lock); From patchwork Thu Mar 6 11:00:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Donnefort X-Patchwork-Id: 14004399 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 9A62CC282D1 for ; Thu, 6 Mar 2025 12:19:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=cvc2qCSEoHcInumCsCUHzJOPxNrN7pZm1b9N0GuNels=; b=210FiICrVlB3qzTYHR9L6/75Sf d6L/CxBY9LyJluyN345NVPpMuPe2i+9AdYwcBNtuW3xo1Ow2ZE7QU9FJhL7IeHKlA9haIA0Unm7CR RWAWNxMnJxft0F6jsIXh/w0sZSoVg1BMamyZkrQ8SstEzIvkwSgRnDTcVb9jaCBRTsxqbi9D/jJCv ZQN/u9ZnmCzAIf3x8gZVgg+Fic0DMxKLihoook+esAOvoOadjyQOBKA6aW1qXYfeA6IueVw7IVC1i hrldVg15Wni6sU+rT8MXRqP436MIW2uJatItTohb97tYc7RAZIkxGc54lxtcSplKGhu9VlSXNQW6h Mtx+tbAQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tqABl-0000000Atb6-1fZW; Thu, 06 Mar 2025 12:18:57 +0000 Received: from mail-wm1-x349.google.com ([2a00:1450:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tq8yQ-0000000Aic6-1PGF for linux-arm-kernel@lists.infradead.org; Thu, 06 Mar 2025 11:01:07 +0000 Received: by mail-wm1-x349.google.com with SMTP id 5b1f17b1804b1-43bc5a18c52so2097815e9.3 for ; Thu, 06 Mar 2025 03:01:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741258864; x=1741863664; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=cvc2qCSEoHcInumCsCUHzJOPxNrN7pZm1b9N0GuNels=; b=ysRLjEAhvHfMfl+cIamFwVtR2v/upiZfNmR9ciMGMnE6/6Vdy4VnqP54+46bJEenno HU/DvpR4Tl+4Vhzv/6A0baAIdjGvJ2ebLHQdXVb/hdtx79vVaHKVvzWXgSK60JCwy1z8 IR8wA1wPel3GAsAbIwgbHHW+PGNzbZRMIOHKHGYG2D9Gq2URqsmTYRuaqLYFTpyqDtak O5o9T2WpQ79s3Vw3e9mH7Djxkztg70eTF1DzttaDb0KbEsdMIrBg77IRn6MzhPUPfwO4 rqZ1rUkGY6G/ParCOMFINz+u0i0wuww+lXuDJQxll4EhKIYCat+Nh521M/dukpOvM6eV SZEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741258864; x=1741863664; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=cvc2qCSEoHcInumCsCUHzJOPxNrN7pZm1b9N0GuNels=; b=KrBQrqAqvFtF+QZjzXDykEnRxO1snyp9KMFIj7wrCB0Awq3oKqyf9THMGc6mxbfaKG Lzq4h0M4UaQagUCjSXw7J6VzZ+KOyaOxmg7kyNdDlWLKkczOxWMXb3dY//IhcqBRC1rX G4AgJMJrUQ5dtwin4jalcTiOH0YJugZQT8S3wLjler8DILeDcM1lRY6dFqhBLZMoCqkg g1HOBUlszGw7cPMw+zZWC+/EbDvmkueqbLObimPExvYP0cYpeVbmFWerBL13BxvZq4qA 80nUxD3+BRa1pk7fn/8bxMBxd+k/IGqrtIhRlxaevywmFQcSyPGP8g+dI2eeH6dvqw95 Arrg== X-Forwarded-Encrypted: i=1; AJvYcCV+4i0gYtYa107GCuznN24sdfq4yI0rEpX4wbAu3XPDJz3RFw9db3xmYDx6j7ZwPWKSDFvcKGuEjQJFx2ls6Ny3@lists.infradead.org X-Gm-Message-State: AOJu0Yx0h4lzuLJA3w9bDFrNsWOZi0+wgsL0CGeyAr0/CJnhfHR87HPH SmJGQWMtaeMu7KdgDTUiyBU+fp8D++mAeOZ6zJ2U3PVhopxmAC/icgLUJM9j07ny+oVFuqVQ/tE piIMrzMwJ1vXm4IhSxQ== X-Google-Smtp-Source: AGHT+IHEXjKh7uYAxIDUZT7+S3GCsAIurCSRFsj7/bmhTfFhgEBZjfPhhhAzv3sciVIkINBKdc3gwmpKNB2CG4iV X-Received: from wmbeu10.prod.google.com ([2002:a05:600c:81ca:b0:43b:bec3:e552]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1c95:b0:439:9b3f:2de1 with SMTP id 5b1f17b1804b1-43bd29ad100mr55221025e9.15.1741258864402; Thu, 06 Mar 2025 03:01:04 -0800 (PST) Date: Thu, 6 Mar 2025 11:00:38 +0000 In-Reply-To: <20250306110038.3733649-1-vdonnefort@google.com> Mime-Version: 1.0 References: <20250306110038.3733649-1-vdonnefort@google.com> X-Mailer: git-send-email 2.48.1.711.g2feabab25a-goog Message-ID: <20250306110038.3733649-10-vdonnefort@google.com> Subject: [PATCH v2 9/9] KVM: arm64: np-guest CMOs with PMD_SIZE fixmap From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_030106_378576_B3B3CFCB X-CRM114-Status: GOOD ( 17.73 ) 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 With the introduction of stage-2 huge mappings in the pKVM hypervisor, guest pages CMO is needed for PMD_SIZE size. Fixmap only supports PAGE_SIZE and iterating over the huge-page is time consuming (mostly due to TLBI on hyp_fixmap_unmap) which is a problem for EL2 latency. Introduce a shared PMD_SIZE fixmap (hyp_fixblock_map/hyp_fixblock_unmap) to improve guest page CMOs when stage-2 huge mappings are installed. On a Pixel6, the iterative solution resulted in a latency of ~700us, while the PMD_SIZE fixmap reduces it to ~100us. Because of the horrendous private range allocation that would be necessary, this is disabled for 64KiB pages systems. Suggested-by: Quentin Perret Signed-off-by: Vincent Donnefort Signed-off-by: Quentin Perret diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index 1b43bcd2a679..2888b5d03757 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -59,6 +59,11 @@ typedef u64 kvm_pte_t; #define KVM_PHYS_INVALID (-1ULL) +#define KVM_PTE_TYPE BIT(1) +#define KVM_PTE_TYPE_BLOCK 0 +#define KVM_PTE_TYPE_PAGE 1 +#define KVM_PTE_TYPE_TABLE 1 + #define KVM_PTE_LEAF_ATTR_LO GENMASK(11, 2) #define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX GENMASK(4, 2) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h index 230e4f2527de..b0c72bc2d5ba 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h @@ -13,9 +13,11 @@ extern struct kvm_pgtable pkvm_pgtable; extern hyp_spinlock_t pkvm_pgd_lock; -int hyp_create_pcpu_fixmap(void); +int hyp_create_fixmap(void); void *hyp_fixmap_map(phys_addr_t phys); void hyp_fixmap_unmap(void); +void *hyp_fixblock_map(phys_addr_t phys); +void hyp_fixblock_unmap(void); int hyp_create_idmap(u32 hyp_va_bits); int hyp_map_vectors(void); diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index b7a995a1d70b..5710c97cafb0 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -220,17 +220,53 @@ static void guest_s2_put_page(void *addr) hyp_put_page(¤t_vm->pool, addr); } +static void *__fixmap_guest_page(void *va, size_t *size) +{ + if (IS_ALIGNED(*size, PMD_SIZE)) { + void *addr = hyp_fixblock_map(__hyp_pa(va)); + + if (addr) + return addr; + + *size = PAGE_SIZE; + } + + if (IS_ALIGNED(*size, PAGE_SIZE)) + return hyp_fixmap_map(__hyp_pa(va)); + + WARN_ON(1); + + return NULL; +} + +static void __fixunmap_guest_page(size_t size) +{ + switch (size) { + case PAGE_SIZE: + hyp_fixmap_unmap(); + break; + case PMD_SIZE: + hyp_fixblock_unmap(); + break; + default: + WARN_ON(1); + } +} + static void clean_dcache_guest_page(void *va, size_t size) { if (WARN_ON(!PAGE_ALIGNED(size))) return; while (size) { - __clean_dcache_guest_page(hyp_fixmap_map(__hyp_pa(va)), - PAGE_SIZE); - hyp_fixmap_unmap(); - va += PAGE_SIZE; - size -= PAGE_SIZE; + size_t fixmap_size = size == PMD_SIZE ? size : PAGE_SIZE; + void *addr = __fixmap_guest_page(va, &fixmap_size); + + __clean_dcache_guest_page(addr, fixmap_size); + __fixunmap_guest_page(fixmap_size); + + size -= fixmap_size; + va += fixmap_size; } } @@ -240,11 +276,14 @@ static void invalidate_icache_guest_page(void *va, size_t size) return; while (size) { - __invalidate_icache_guest_page(hyp_fixmap_map(__hyp_pa(va)), - PAGE_SIZE); - hyp_fixmap_unmap(); - va += PAGE_SIZE; - size -= PAGE_SIZE; + size_t fixmap_size = size == PMD_SIZE ? size : PAGE_SIZE; + void *addr = __fixmap_guest_page(va, &fixmap_size); + + __invalidate_icache_guest_page(addr, fixmap_size); + __fixunmap_guest_page(fixmap_size); + + size -= fixmap_size; + va += fixmap_size; } } diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c index f41c7440b34b..e3b1bece8504 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -229,9 +229,8 @@ int hyp_map_vectors(void) return 0; } -void *hyp_fixmap_map(phys_addr_t phys) +static void *fixmap_map_slot(struct hyp_fixmap_slot *slot, phys_addr_t phys) { - struct hyp_fixmap_slot *slot = this_cpu_ptr(&fixmap_slots); kvm_pte_t pte, *ptep = slot->ptep; pte = *ptep; @@ -243,10 +242,21 @@ void *hyp_fixmap_map(phys_addr_t phys) return (void *)slot->addr; } +void *hyp_fixmap_map(phys_addr_t phys) +{ + return fixmap_map_slot(this_cpu_ptr(&fixmap_slots), phys); +} + static void fixmap_clear_slot(struct hyp_fixmap_slot *slot) { kvm_pte_t *ptep = slot->ptep; u64 addr = slot->addr; + u32 level; + + if (FIELD_GET(KVM_PTE_TYPE, *ptep) == KVM_PTE_TYPE_PAGE) + level = KVM_PGTABLE_LAST_LEVEL; + else + level = KVM_PGTABLE_LAST_LEVEL - 1; /* create_fixblock() guarantees PMD level */ WRITE_ONCE(*ptep, *ptep & ~KVM_PTE_VALID); @@ -260,7 +270,7 @@ static void fixmap_clear_slot(struct hyp_fixmap_slot *slot) * https://lore.kernel.org/kvm/20221017115209.2099-1-will@kernel.org/T/#mf10dfbaf1eaef9274c581b81c53758918c1d0f03 */ dsb(ishst); - __tlbi_level(vale2is, __TLBI_VADDR(addr, 0), KVM_PGTABLE_LAST_LEVEL); + __tlbi_level(vale2is, __TLBI_VADDR(addr, 0), level); dsb(ish); isb(); } @@ -273,9 +283,9 @@ void hyp_fixmap_unmap(void) static int __create_fixmap_slot_cb(const struct kvm_pgtable_visit_ctx *ctx, enum kvm_pgtable_walk_flags visit) { - struct hyp_fixmap_slot *slot = per_cpu_ptr(&fixmap_slots, (u64)ctx->arg); + struct hyp_fixmap_slot *slot = (struct hyp_fixmap_slot *)ctx->arg; - if (!kvm_pte_valid(ctx->old) || ctx->level != KVM_PGTABLE_LAST_LEVEL) + if (!kvm_pte_valid(ctx->old) || (ctx->end - ctx->start) != kvm_granule_size(ctx->level)) return -EINVAL; slot->addr = ctx->addr; @@ -296,13 +306,73 @@ static int create_fixmap_slot(u64 addr, u64 cpu) struct kvm_pgtable_walker walker = { .cb = __create_fixmap_slot_cb, .flags = KVM_PGTABLE_WALK_LEAF, - .arg = (void *)cpu, + .arg = (void *)per_cpu_ptr(&fixmap_slots, cpu), }; return kvm_pgtable_walk(&pkvm_pgtable, addr, PAGE_SIZE, &walker); } -int hyp_create_pcpu_fixmap(void) +#ifndef CONFIG_ARM64_64K_PAGES +static struct hyp_fixmap_slot hyp_fixblock_slot; +static DEFINE_HYP_SPINLOCK(hyp_fixblock_lock); + +void *hyp_fixblock_map(phys_addr_t phys) +{ + hyp_spin_lock(&hyp_fixblock_lock); + return fixmap_map_slot(&hyp_fixblock_slot, phys); +} + +void hyp_fixblock_unmap(void) +{ + fixmap_clear_slot(&hyp_fixblock_slot); + hyp_spin_unlock(&hyp_fixblock_lock); +} + +static int create_fixblock(void) +{ + struct kvm_pgtable_walker walker = { + .cb = __create_fixmap_slot_cb, + .flags = KVM_PGTABLE_WALK_LEAF, + .arg = (void *)&hyp_fixblock_slot, + }; + unsigned long addr; + phys_addr_t phys; + int ret, i; + + /* Find a RAM phys address, PMD aligned */ + for (i = 0; i < hyp_memblock_nr; i++) { + phys = ALIGN(hyp_memory[i].base, PMD_SIZE); + if (phys + PMD_SIZE < (hyp_memory[i].base + hyp_memory[i].size)) + break; + } + + if (i >= hyp_memblock_nr) + return -EINVAL; + + hyp_spin_lock(&pkvm_pgd_lock); + addr = ALIGN(__io_map_base, PMD_SIZE); + ret = __pkvm_alloc_private_va_range(addr, PMD_SIZE); + if (ret) + goto unlock; + + ret = kvm_pgtable_hyp_map(&pkvm_pgtable, addr, PMD_SIZE, phys, PAGE_HYP); + if (ret) + goto unlock; + + ret = kvm_pgtable_walk(&pkvm_pgtable, addr, PMD_SIZE, &walker); + +unlock: + hyp_spin_unlock(&pkvm_pgd_lock); + + return ret; +} +#else +void hyp_fixblock_unmap(void) { WARN_ON(1); } +void *hyp_fixblock_map(phys_addr_t phys) { return NULL; } +static int create_fixblock(void) { return 0; } +#endif + +int hyp_create_fixmap(void) { unsigned long addr, i; int ret; @@ -322,7 +392,7 @@ int hyp_create_pcpu_fixmap(void) return ret; } - return 0; + return create_fixblock(); } int hyp_create_idmap(u32 hyp_va_bits) diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index d62bcb5634a2..fb69cf5e6ea8 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -295,7 +295,7 @@ void __noreturn __pkvm_init_finalise(void) if (ret) goto out; - ret = hyp_create_pcpu_fixmap(); + ret = hyp_create_fixmap(); if (ret) goto out; diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index df5cc74a7dd0..c351b4abd5db 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -11,12 +11,6 @@ #include #include - -#define KVM_PTE_TYPE BIT(1) -#define KVM_PTE_TYPE_BLOCK 0 -#define KVM_PTE_TYPE_PAGE 1 -#define KVM_PTE_TYPE_TABLE 1 - struct kvm_pgtable_walk_data { struct kvm_pgtable_walker *walker;