From patchwork Fri Jan 22 08:36:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: zhukeqian X-Patchwork-Id: 12038629 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=-16.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,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 E1670C433E0 for ; Fri, 22 Jan 2021 08:38:46 +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 91580235F9 for ; Fri, 22 Jan 2021 08:38:46 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 91580235F9 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com 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: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:In-Reply-To:References:List-Owner; bh=di0GdO75SXncETI2nKwSqqWC6GwfmJCmMU/VQRjPpeQ=; b=jToyw2S5amwOEOsW8KK2BE+AwW iA8wtw5vJNqP1xJJeaAg8bYTfn6/0rc1cgVcc5+WrbV4j9Uj/ZwXFdB/7IGs2fYbu8apRe/WThnP9 cGujTB86xzhz9zZJ61z9Hv/QcwpeJXtSOuFCvBTQn1LyhZJpWuE8dW59JQphlkeRq3imllHwaf9W7 rKHj5z59+Vo4YiDW0m87v/pUhVrmn1sGcPaMF/71qD6XFNEVgZ7lIDXzx29+FgAFfi9ZnwbqgErnN nStbuY0vurH1d2JiFQHRFvW6Dk+mm+oeK3VJFKxEWILBCmIWN0ByfsuAcioWaRFzxQ02FZCVaheRO z02J1NjA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l2rwV-00071g-Qc; Fri, 22 Jan 2021 08:37:19 +0000 Received: from szxga04-in.huawei.com ([45.249.212.190]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l2rwS-0006zm-TN for linux-arm-kernel@lists.infradead.org; Fri, 22 Jan 2021 08:37:18 +0000 Received: from DGGEMS412-HUB.china.huawei.com (unknown [172.30.72.60]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4DMXdn4gT6zl8Rv; Fri, 22 Jan 2021 16:35:41 +0800 (CST) Received: from DESKTOP-5IS4806.china.huawei.com (10.174.184.42) by DGGEMS412-HUB.china.huawei.com (10.3.19.212) with Microsoft SMTP Server id 14.3.498.0; Fri, 22 Jan 2021 16:37:01 +0800 From: Keqian Zhu To: , , , , Will Deacon , Marc Zyngier , Catalin Marinas Subject: [RFC PATCH] kvm: arm64: Try stage2 block mapping for host device MMIO Date: Fri, 22 Jan 2021 16:36:50 +0800 Message-ID: <20210122083650.21812-1-zhukeqian1@huawei.com> X-Mailer: git-send-email 2.8.4.windows.1 MIME-Version: 1.0 X-Originating-IP: [10.174.184.42] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210122_033717_449055_B6253F3B X-CRM114-Status: GOOD ( 14.36 ) 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: Mark Rutland , jiangkunkun@huawei.com, Suzuki K Poulose , Joerg Roedel , Daniel Lezcano , Alexios Zavras , James Morse , wanghaibin.wang@huawei.com, Thomas Gleixner , Robin Murphy , Andrew Morton , Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The MMIO region of a device maybe huge (GB level), try to use block mapping in stage2 to speedup both map and unmap. Especially for unmap, it performs TLBI right after each invalidation of PTE. If all mapping is of PAGE_SIZE, it takes much time to handle GB level range. Signed-off-by: Keqian Zhu --- arch/arm64/include/asm/kvm_pgtable.h | 11 +++++++++++ arch/arm64/kvm/hyp/pgtable.c | 15 +++++++++++++++ arch/arm64/kvm/mmu.c | 12 ++++++++---- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index 52ab38db04c7..2266ac45f10c 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -82,6 +82,17 @@ struct kvm_pgtable_walker { const enum kvm_pgtable_walk_flags flags; }; +/** + * kvm_supported_pgsize() - Get the max supported page size of a mapping. + * @pgt: Initialised page-table structure. + * @addr: Virtual address at which to place the mapping. + * @end: End virtual address of the mapping. + * @phys: Physical address of the memory to map. + * + * The smallest return value is PAGE_SIZE. + */ +u64 kvm_supported_pgsize(struct kvm_pgtable *pgt, u64 addr, u64 end, u64 phys); + /** * kvm_pgtable_hyp_init() - Initialise a hypervisor stage-1 page-table. * @pgt: Uninitialised page-table structure to initialise. diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index bdf8e55ed308..ab11609b9b13 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -81,6 +81,21 @@ static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level) return IS_ALIGNED(addr, granule) && IS_ALIGNED(phys, granule); } +u64 kvm_supported_pgsize(struct kvm_pgtable *pgt, u64 addr, u64 end, u64 phys) +{ + u32 lvl; + u64 pgsize = PAGE_SIZE; + + for (lvl = pgt->start_level; lvl < KVM_PGTABLE_MAX_LEVELS; lvl++) { + if (kvm_block_mapping_supported(addr, end, phys, lvl)) { + pgsize = kvm_granule_size(lvl); + break; + } + } + + return pgsize; +} + static u32 kvm_pgtable_idx(struct kvm_pgtable_walk_data *data, u32 level) { u64 shift = kvm_granule_shift(level); diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 7d2257cc5438..80b403fc8e64 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -499,7 +499,8 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu) int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, phys_addr_t pa, unsigned long size, bool writable) { - phys_addr_t addr; + phys_addr_t addr, end; + unsigned long pgsize; int ret = 0; struct kvm_mmu_memory_cache cache = { 0, __GFP_ZERO, NULL, }; struct kvm_pgtable *pgt = kvm->arch.mmu.pgt; @@ -509,21 +510,24 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, size += offset_in_page(guest_ipa); guest_ipa &= PAGE_MASK; + end = guest_ipa + size; - for (addr = guest_ipa; addr < guest_ipa + size; addr += PAGE_SIZE) { + for (addr = guest_ipa; addr < end; addr += pgsize) { ret = kvm_mmu_topup_memory_cache(&cache, kvm_mmu_cache_min_pages(kvm)); if (ret) break; + pgsize = kvm_supported_pgsize(pgt, addr, end, pa); + spin_lock(&kvm->mmu_lock); - ret = kvm_pgtable_stage2_map(pgt, addr, PAGE_SIZE, pa, prot, + ret = kvm_pgtable_stage2_map(pgt, addr, pgsize, pa, prot, &cache); spin_unlock(&kvm->mmu_lock); if (ret) break; - pa += PAGE_SIZE; + pa += pgsize; } kvm_mmu_free_memory_cache(&cache);