From patchwork Thu Sep 10 13:33:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 11767847 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7C44014F6 for ; Thu, 10 Sep 2020 13:33:35 +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 1A07C2087C for ; Thu, 10 Sep 2020 13:33:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="dCt1xTEH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1A07C2087C Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.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=YO/Jrh5ePxGavLwwgbXAdAbuvBZM1+3zDTFNItW4OYU=; b=dCt1xTEHF0Vh7fT8+gX2LoXhiS 3G5FdlF5b7KyoAHvrELzrYjjs1hZQGr2JeWKlDQ7iEzhnJbbchgnjdb5aHlroBr94V6u/Ma4Cc6Uy OSZavCnsKot3yZiUKeuCnEjmEuBdn85sJxhFZzlS1YUIc+uxJ6MRpuzYbHotyD8ynqWQViNeqHyq9 eHc0mmT75UX/evCCXwwfADDBnvTbQAnfu+O2uuLPLU9nHu4ZXG3wzgDo3LSJW1DGqmn1nLLLlelnZ l/jufKD5yJo7g3Dxn+5PvQcP5xllbTi4i2jVWlyw6mz4quCWHC1R7o3Q0naeZ9FFqQMHG7AXrjcln 1JgeGeHQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kGMhT-0007Xx-C1; Thu, 10 Sep 2020 13:33:19 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kGMhR-0007Xb-27 for linux-arm-kernel@lists.infradead.org; Thu, 10 Sep 2020 13:33:18 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B06EA106F; Thu, 10 Sep 2020 06:33:14 -0700 (PDT) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A21663F66E; Thu, 10 Sep 2020 06:33:13 -0700 (PDT) From: Alexandru Elisei To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu Subject: [PATCH v2] KVM: arm64: Try PMD block mappings if PUD mappings are not supported Date: Thu, 10 Sep 2020 14:33:51 +0100 Message-Id: <20200910133351.118191-1-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200910_093317_151136_2DCC174C X-CRM114-Status: GOOD ( 18.03 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [217.140.110.172 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 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: maz@kernel.org, james.morse@arm.com, punit1.agrawal@toshiba.co.jp, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org When userspace uses hugetlbfs for the VM memory, user_mem_abort() tries to use the same block size to map the faulting IPA in stage 2. If stage 2 cannot the same block mapping because the block size doesn't fit in the memslot or the memslot is not properly aligned, user_mem_abort() will fall back to a page mapping, regardless of the block size. We can do better for PUD backed hugetlbfs by checking if a PMD block mapping is supported before deciding to use a page. vma_pagesize is an unsigned long, use 1UL instead of 1ULL when assigning its value. Signed-off-by: Alexandru Elisei --- Tested on a rockpro64 with 4K pages and hugetlbfs hugepagesz=1G (PUD sized block mappings). First test, guest RAM starts at 0x8100 0000 (memslot->base_gfn not aligned to 1GB); second test, guest RAM starts at 0x8000 0000, but is only 512 MB. In both cases using PUD mappings is not possible because either the memslot base address is not aligned, or the mapping would extend beyond the memslot. Without the changes, user_mem_abort() uses 4K pages to map the guest IPA. With the patches, user_mem_abort() uses PMD block mappings (2MB) to map the guest RAM, which means less TLB pressure and fewer stage 2 aborts. Changes since v1 [1]: - Rebased on top of Will's stage 2 page table handling rewrite, version 4 of the series [2]. His series is missing the patch "KVM: arm64: Update page shift if stage 2 block mapping not supported" and there might be a conflict (it's straightforward to fix). [1] https://www.spinics.net/lists/arm-kernel/msg834015.html [2] https://www.spinics.net/lists/arm-kernel/msg835806.html arch/arm64/kvm/mmu.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 1041be1fafe4..39c539d4d4cb 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -776,16 +776,25 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, else vma_shift = PAGE_SHIFT; - vma_pagesize = 1ULL << vma_shift; if (logging_active || - (vma->vm_flags & VM_PFNMAP) || - !fault_supports_stage2_huge_mapping(memslot, hva, vma_pagesize)) { + (vma->vm_flags & VM_PFNMAP)) { force_pte = true; - vma_pagesize = PAGE_SIZE; + vma_shift = PAGE_SHIFT; + } + + if (vma_shift == PUD_SHIFT && + !fault_supports_stage2_huge_mapping(memslot, hva, PUD_SIZE)) + vma_shift = PMD_SHIFT; + + if (vma_shift == PMD_SHIFT && + !fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE)) { + force_pte = true; + vma_shift = PAGE_SHIFT; } + vma_pagesize = 1UL << vma_shift; if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE) - fault_ipa &= huge_page_mask(hstate_vma(vma)); + fault_ipa &= ~(vma_pagesize - 1); gfn = fault_ipa >> PAGE_SHIFT; mmap_read_unlock(current->mm);