From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49967C433E0 for ; Thu, 30 Jul 2020 15:37:30 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1A36B2082E for ; Thu, 30 Jul 2020 15:37:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="FVKKbMKW"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="kYqFyqkQ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1A36B2082E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=8pTiKrxNR2uRxpJsMhbET4hu84XQ0UJnbzK3dRnuxuQ=; b=FVKKbMKWobnXA1Jro3aLq4cLx 3iO8ThLferK8+6UTFjZb9nX6j5DwXz9t4zX8NuBxSfRPpow9n5KWTBQcPVJVeOaQ75mS+wSWSUeDh UTxLLyOn/fmUl10UwzUR/yshR88Z99ENeWktbOJT3zEJO/vQW+fDsmn53od0WsGS8eWZ8RIJdIJp3 5CiNlzwa9DLzhvSdVpRzeKUUgEpiyojlahjqZEu1rl2R7Iipu4nZUUCranj7DChNkRcArXGIi5M7U IQA1aSxxd/L8g/ZOiuXm48sOW1dC4AH2IFcXS/QDU5rgMACGGJpd6G6pGaGhkOCIIgatf2gKfmcm0 kCVhtElqQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k1AaT-00029b-7U; Thu, 30 Jul 2020 15:35:17 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1k1AZo-0001up-HG for linux-arm-kernel@lists.infradead.org; Thu, 30 Jul 2020 15:34:38 +0000 Received: from localhost.localdomain (236.31.169.217.in-addr.arpa [217.169.31.236]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6A9F922B3F; Thu, 30 Jul 2020 15:34:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596123276; bh=X1fA8dHgKFfF8MZnKA6jQkpX4iheWR/EpsLF4ki0G90=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kYqFyqkQWNEcdIUZlvRD8LZM8vU9hEr9klwX/6y3BvsKKMi/NcVs5Lwp6lwf8CrFQ wSbF+D4/r3Jt7o9BH/aLQGpv+XgRdNRYvO6dGWNIu00SSyb/BFLZQZzFbSCxg3tZ9V GDXsYrzuKIIzgKVmYDM/ZDBmX+q1eMwqJ95DxcvM= From: Will Deacon To: kvmarm@lists.cs.columbia.edu Subject: [PATCH 08/20] KVM: arm64: Convert unmap_stage2_range() to generic page-table API Date: Thu, 30 Jul 2020 16:33:54 +0100 Message-Id: <20200730153406.25136-9-will@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200730153406.25136-1-will@kernel.org> References: <20200730153406.25136-1-will@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200730_113437_659605_5659DD8F X-CRM114-Status: GOOD ( 18.87 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel-team@android.com, Suzuki Poulose , Marc Zyngier , Quentin Perret , James Morse , Catalin Marinas , Will Deacon , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Convert unmap_stage2_range() to use kvm_pgtable_stage2_unmap() instead of walking the page-table directly. Cc: Marc Zyngier Cc: Quentin Perret Signed-off-by: Will Deacon --- arch/arm64/kvm/mmu.c | 58 +++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index f6b7220412af..d2ce44183b98 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -39,6 +39,32 @@ static bool is_iomap(unsigned long flags) return flags & KVM_S2PTE_FLAG_IS_IOMAP; } +/* + * Release kvm_mmu_lock periodically if the memory region is large. Otherwise, + * we may see kernel panics with CONFIG_DETECT_HUNG_TASK, + * CONFIG_LOCKUP_DETECTOR, CONFIG_LOCKDEP. Additionally, holding the lock too + * long will also starve other vCPUs. We have to also make sure that the page + * tables are not freed while we released the lock. + */ +#define stage2_apply_range_resched(kvm, addr, end, fn) \ +({ \ + int ret; \ + struct kvm *__kvm = (kvm); \ + u64 next, __addr = (addr), __end = (end); \ + do { \ + void *cookie = __kvm->arch.mmu.pgt_cookie; \ + if (!cookie) \ + break; \ + next = stage2_pgd_addr_end(__kvm, __addr, __end); \ + ret = fn(cookie, __addr, next - __addr); \ + if (ret) \ + break; \ + if (next != __end) \ + cond_resched_lock(&__kvm->mmu_lock); \ + } while (__addr = next, __addr != __end); \ + ret; \ +}) + static bool memslot_is_logging(struct kvm_memory_slot *memslot) { return memslot->dirty_bitmap && !(memslot->flags & KVM_MEM_READONLY); @@ -256,8 +282,8 @@ static inline void kvm_pgd_populate(pgd_t *pgdp, p4d_t *p4dp) * end up writing old data to disk. * * This is why right after unmapping a page/section and invalidating - * the corresponding TLBs, we call kvm_flush_dcache_p*() to make sure - * the IO subsystem will never hit in the cache. + * the corresponding TLBs, we flush to make sure the IO subsystem will + * never hit in the cache. * * This is all avoided on systems that have ARM64_HAS_STAGE2_FWB, as * we then fully enforce cacheability of RAM, no matter what the guest @@ -375,36 +401,18 @@ static void unmap_stage2_p4ds(struct kvm_s2_mmu *mmu, pgd_t *pgd, * be called while holding mmu_lock (unless for freeing the stage2 pgd before * destroying the VM), otherwise another faulting VCPU may come in and mess * with things behind our backs. + * + * Return: 0 on success, negative error code on failure. */ static void unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size) { struct kvm *kvm = mmu->kvm; - pgd_t *pgd; - phys_addr_t addr = start, end = start + size; - phys_addr_t next; + phys_addr_t end = start + size; assert_spin_locked(&kvm->mmu_lock); WARN_ON(size & ~PAGE_MASK); - - pgd = mmu->pgd + stage2_pgd_index(kvm, addr); - do { - /* - * Make sure the page table is still active, as another thread - * could have possibly freed the page table, while we released - * the lock. - */ - if (!READ_ONCE(mmu->pgd)) - break; - next = stage2_pgd_addr_end(kvm, addr, end); - if (!stage2_pgd_none(kvm, *pgd)) - unmap_stage2_p4ds(mmu, pgd, addr, next); - /* - * If the range is too large, release the kvm->mmu_lock - * to prevent starvation and lockup detector warnings. - */ - if (next != end) - cond_resched_lock(&kvm->mmu_lock); - } while (pgd++, addr = next, addr != end); + WARN_ON(stage2_apply_range_resched(kvm, start, end, + kvm_pgtable_stage2_unmap)); } static void stage2_flush_ptes(struct kvm_s2_mmu *mmu, pmd_t *pmd, -- 2.28.0.rc0.142.g3c755180ce-goog _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel