From patchwork Sun Apr 23 17:08:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9695133 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 97F35601E9 for ; Sun, 23 Apr 2017 17:24:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D93B203B9 for ; Sun, 23 Apr 2017 17:24:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 825A2262F2; Sun, 23 Apr 2017 17:24:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8CFEF203B9 for ; Sun, 23 Apr 2017 17:24:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: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=NAaJajDCxuIm4wwY5/t8lzf1TBcX6GLanPtnM0QGUxk=; b=qdud+zEw+OaKjQ1y8rCtTXhfed lGeuujutk9mpmNUBbBdfoRnlH7rNQO2Q6dJnfejt+M9+eB8aBWytlXhCmFg623CrqT0E3Ro88Y+Ew ZCCQygl8fc9NnJTxfP495KbuvrnLXrsT+O45EJkwgwae33kldlNWLDY4tuqX6UTFmt29zJbLBQaKI MtDkcFlnumsIz79jLLbJscjlyvJuoj2s0xHTxUkscjhhY63SCs9r/io6TfK9ma095iTIuniszKb3e KY6zzzalpTS873nJBSOH7PDNfWFoMy/JwTqG3FyBfTiC79S7mn3geOTWCraoFqdGRjKjpaTTkToxf rU3u1sfQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1d2LFJ-0006MP-2s; Sun, 23 Apr 2017 17:24:25 +0000 Received: from mail-wm0-x22a.google.com ([2a00:1450:400c:c09::22a]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1d2L1V-0004V5-Uy for linux-arm-kernel@lists.infradead.org; Sun, 23 Apr 2017 17:10:18 +0000 Received: by mail-wm0-x22a.google.com with SMTP id r190so50446969wme.1 for ; Sun, 23 Apr 2017 10:09:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nhADLxWU4woGh/WLgZKhyve/4E63P0dRFz9DNnwee+g=; b=QZffPS+3XNpYX7wirrb4uV3kgAq9r3y9kGlCF9D6XX2+4bqVf0zD71h4ERpf3B1S2j d/3jDH2EXL/Z11T44hcKSdWY9nTMCB3JYYGurM369QGEqPxdWWG7xaBLxVU/oPgymhZG kXDEFBzguxlpZNtBk11IBkG+s6WJtEH2CpQHI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nhADLxWU4woGh/WLgZKhyve/4E63P0dRFz9DNnwee+g=; b=hJQCNnxfsmnAOFAqqZYOGVKkCLXx7+1z8kTLq+lQGHtk7LuaKCdOlWP6r6+/Gcf6oX N2ChlkSV09YTOPRJDFGaWt0LDsDa8/8J1GdN3qFRCIiO4r9sBSSjrKR4u0MfLBjQ07Xn +e8gpFpSUyGdaUGI2BYQBe4gljCHaZYTweP+uY4sg/PJkQ3GkGFtUzIr//SFDsNh2hPp r2wkRZRehNW/J9xvEn47IOgi/vu4iyYCOwSRgHfpn7H6r4NeeOexalVql9yLDkVsLaA2 XTAR/5IsEqhtAT3bA9MCtbEkc0TbDDIitFoemmcEuNy2neQ/P2eAosceAErLktXYr05d bRCQ== X-Gm-Message-State: AN3rC/73twfZGywyHKdH5yd5hRHPiILFBDBzFx/DU+t54EZ+x1prVLc8 DIdk793ebBQBLshx X-Received: by 10.80.196.76 with SMTP id w12mr141062edf.155.1492967387988; Sun, 23 Apr 2017 10:09:47 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id 58sm2803521edz.2.2017.04.23.10.09.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 23 Apr 2017 10:09:47 -0700 (PDT) From: Christoffer Dall To: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Subject: [PULL 16/79] kvm: arm/arm64: Rework gpa callback handlers Date: Sun, 23 Apr 2017 19:08:26 +0200 Message-Id: <20170423170929.27334-17-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170423170929.27334-1-cdall@linaro.org> References: <20170423170929.27334-1-cdall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170423_101010_651125_C2BC70B2 X-CRM114-Status: GOOD ( 14.57 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Christoffer Dall , kvm@vger.kernel.org, Suzuki K Poulose , Marc Zyngier , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Suzuki K Poulose In order to perform an operation on a gpa range, we currently iterate over each page in a user memory slot for the given range. This is inefficient while dealing with a big range (e.g, a VMA), especially while unmaping a range. At present, with stage2 unmap on a range with a hugepage backed region, we clear the PMD when we unmap the first page in the loop. The remaining iterations simply traverse the page table down to the PMD level only to see that nothing is in there. This patch reworks the code to invoke the callback handlers on the biggest range possible within the memory slot to to reduce the number of times the handler is called. Cc: Marc Zyngier Reviewed-by: Christoffer Dall Signed-off-by: Suzuki K Poulose Signed-off-by: Christoffer Dall --- arch/arm/kvm/mmu.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 962616f..69554bd 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -1512,7 +1512,8 @@ static int handle_hva_to_gpa(struct kvm *kvm, unsigned long start, unsigned long end, int (*handler)(struct kvm *kvm, - gpa_t gpa, void *data), + gpa_t gpa, u64 size, + void *data), void *data) { struct kvm_memslots *slots; @@ -1524,7 +1525,7 @@ static int handle_hva_to_gpa(struct kvm *kvm, /* we only care about the pages that the guest sees */ kvm_for_each_memslot(memslot, slots) { unsigned long hva_start, hva_end; - gfn_t gfn, gfn_end; + gfn_t gpa; hva_start = max(start, memslot->userspace_addr); hva_end = min(end, memslot->userspace_addr + @@ -1532,25 +1533,16 @@ static int handle_hva_to_gpa(struct kvm *kvm, if (hva_start >= hva_end) continue; - /* - * {gfn(page) | page intersects with [hva_start, hva_end)} = - * {gfn_start, gfn_start+1, ..., gfn_end-1}. - */ - gfn = hva_to_gfn_memslot(hva_start, memslot); - gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot); - - for (; gfn < gfn_end; ++gfn) { - gpa_t gpa = gfn << PAGE_SHIFT; - ret |= handler(kvm, gpa, data); - } + gpa = hva_to_gfn_memslot(hva_start, memslot) << PAGE_SHIFT; + ret |= handler(kvm, gpa, (u64)(hva_end - hva_start), data); } return ret; } -static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) +static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data) { - unmap_stage2_range(kvm, gpa, PAGE_SIZE); + unmap_stage2_range(kvm, gpa, size); return 0; } @@ -1577,10 +1569,11 @@ int kvm_unmap_hva_range(struct kvm *kvm, return 0; } -static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data) +static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data) { pte_t *pte = (pte_t *)data; + WARN_ON(size != PAGE_SIZE); /* * We can always call stage2_set_pte with KVM_S2PTE_FLAG_LOGGING_ACTIVE * flag clear because MMU notifiers will have unmapped a huge PMD before @@ -1606,11 +1599,12 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte); } -static int kvm_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) +static int kvm_age_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data) { pmd_t *pmd; pte_t *pte; + WARN_ON(size != PAGE_SIZE && size != PMD_SIZE); pmd = stage2_get_pmd(kvm, NULL, gpa); if (!pmd || pmd_none(*pmd)) /* Nothing there */ return 0; @@ -1625,11 +1619,12 @@ static int kvm_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) return stage2_ptep_test_and_clear_young(pte); } -static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) +static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data) { pmd_t *pmd; pte_t *pte; + WARN_ON(size != PAGE_SIZE && size != PMD_SIZE); pmd = stage2_get_pmd(kvm, NULL, gpa); if (!pmd || pmd_none(*pmd)) /* Nothing there */ return 0;