Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp3508001pxb; Wed, 14 Apr 2021 07:07:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwU93B1igkNdjDjsVFOFY7C3eAs2ws76lOHr+lrnKDe6hoIEWvn6Xg1oof1llwMBNqteXaz X-Received: by 2002:a05:6402:94b:: with SMTP id h11mr35253942edz.180.1618409245702; Wed, 14 Apr 2021 07:07:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618409245; cv=none; d=google.com; s=arc-20160816; b=UtYgcmLtd8+so3Ii8by+Mu1CMxCykMM8bHZPj5mOLr0+KIkNzutk0zL3ElQ4t6LBCJ MxhKJUjx5DGXpV/8/R+oFVwbAsxGj40Q8wuPg2mXT4AgGWZNvyDLiNmELjTuQKTHoA5Z +NqEyh2p9YefK7UfM4aOHO2th+CmC3znYya+ebJ+pJevw0XYEDHW8lL7eVbrQ9ziai3Y EP85w5NCJivYYIz4Le0SNX4ngcVdp7hZD0LvlzA4SWZTkoiiObntECTDVxB9nCbNx9D3 4m8QFJjVY3HMooaPZ5mELqt07a1X+1k4uepH000b2LNaEYFxqG+3lqnpXQyN0B6Mx5gl wptw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from; bh=aFd/Nyxe6j5ME1fW2k09da9gKmWx38vr/j6c7s3C2iU=; b=HWEBBHGvEJOVcYABd/cQYuCaOvegrWzo7JTKXIZ0KkpLngvmraGQKBekPpfToKehRr uvqxFwM7nAqcgslAwdH16nXbxCKelZcjwqXDldPnShMQ2mm8kK/+09pXLIpy0gjJ5mIW 2LjLyzdtSK+oz/9CS8jxst18rC+ZSTI7xhl9LOPari7AJZ8ODDFx6pnC+bBMfih+WQLq G3+TxE7si8rUNcH7uRwQ8meVTVrxgFX5WHYDWsJkL/kJWiztW5vY7gczsSJM0/JgawT+ V+nq1L4gV5ogsNoLS8frhe+vxVHpIH+kyb3N+G0iPEN4P1FQYBswPLLW1aacCu67uk0+ gXIQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b21si12420899eds.152.2021.04.14.07.07.00; Wed, 14 Apr 2021 07:07:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349442AbhDNGw3 (ORCPT + 99 others); Wed, 14 Apr 2021 02:52:29 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:16993 "EHLO szxga05-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349419AbhDNGwZ (ORCPT ); Wed, 14 Apr 2021 02:52:25 -0400 Received: from DGGEMS402-HUB.china.huawei.com (unknown [172.30.72.58]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4FKtNz4Np5zNw2V; Wed, 14 Apr 2021 14:49:07 +0800 (CST) Received: from DESKTOP-5IS4806.china.huawei.com (10.174.187.224) by DGGEMS402-HUB.china.huawei.com (10.3.19.202) with Microsoft SMTP Server id 14.3.498.0; Wed, 14 Apr 2021 14:51:55 +0800 From: Keqian Zhu To: , , , , Marc Zyngier CC: Subject: [PATCH v3 2/2] kvm/arm64: Try stage2 block mapping for host device MMIO Date: Wed, 14 Apr 2021 14:51:09 +0800 Message-ID: <20210414065109.8616-3-zhukeqian1@huawei.com> X-Mailer: git-send-email 2.8.4.windows.1 In-Reply-To: <20210414065109.8616-1-zhukeqian1@huawei.com> References: <20210414065109.8616-1-zhukeqian1@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.174.187.224] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The MMIO region of a device maybe huge (GB level), try to use block mapping in stage2 to speedup both map and unmap. Compared to normal memory mapping, we should consider two more points when try block mapping for MMIO region: 1. For normal memory mapping, the PA(host physical address) and HVA have same alignment within PUD_SIZE or PMD_SIZE when we use the HVA to request hugepage, so we don't need to consider PA alignment when verifing block mapping. But for device memory mapping, the PA and HVA may have different alignment. 2. For normal memory mapping, we are sure hugepage size properly fit into vma, so we don't check whether the mapping size exceeds the boundary of vma. But for device memory mapping, we should pay attention to this. This adds device_rough_page_shift() to check these two points when selecting block mapping size. Signed-off-by: Keqian Zhu --- arch/arm64/kvm/mmu.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index c59af5ca01b0..1a6d96169d60 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -624,6 +624,31 @@ static void kvm_send_hwpoison_signal(unsigned long address, short lsb) send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, current); } +/* + * Find a max mapping size that properly insides the vma. And hva and pa must + * have the same alignment to this mapping size. It's rough as there are still + * other restrictions, will be checked by fault_supports_stage2_huge_mapping(). + */ +static short device_rough_page_shift(struct vm_area_struct *vma, + unsigned long hva) +{ + phys_addr_t pa = (vma->vm_pgoff << PAGE_SHIFT) + (hva - vma->vm_start); + +#ifndef __PAGETABLE_PMD_FOLDED + if ((hva & (PUD_SIZE - 1)) == (pa & (PUD_SIZE - 1)) && + ALIGN_DOWN(hva, PUD_SIZE) >= vma->vm_start && + ALIGN(hva, PUD_SIZE) <= vma->vm_end) + return PUD_SHIFT; +#endif + + if ((hva & (PMD_SIZE - 1)) == (pa & (PMD_SIZE - 1)) && + ALIGN_DOWN(hva, PMD_SIZE) >= vma->vm_start && + ALIGN(hva, PMD_SIZE) <= vma->vm_end) + return PMD_SHIFT; + + return PAGE_SHIFT; +} + static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot, unsigned long hva, unsigned long map_size) @@ -769,7 +794,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, return -EFAULT; } - /* Let's check if we will get back a huge page backed by hugetlbfs */ + /* + * Let's check if we will get back a huge page backed by hugetlbfs, or + * get block mapping for device MMIO region. + */ mmap_read_lock(current->mm); vma = find_vma_intersection(current->mm, hva, hva + 1); if (unlikely(!vma)) { @@ -780,11 +808,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (is_vm_hugetlb_page(vma)) vma_shift = huge_page_shift(hstate_vma(vma)); + else if (vma->vm_flags & VM_PFNMAP) + vma_shift = device_rough_page_shift(vma, hva); else vma_shift = PAGE_SHIFT; - if (logging_active || - (vma->vm_flags & VM_PFNMAP)) { + if (logging_active) { force_pte = true; vma_shift = PAGE_SHIFT; } @@ -855,7 +884,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (kvm_is_device_pfn(pfn)) { device = true; - force_pte = true; + force_pte = (vma_pagesize == PAGE_SIZE); } else if (logging_active && !write_fault) { /* * Only actually map the page as writable if this was a write -- 2.19.1