From patchwork Mon Aug 12 04:12:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 2842848 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 01AEA9F239 for ; Mon, 12 Aug 2013 04:13:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2BAFB20284 for ; Mon, 12 Aug 2013 04:13:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EDB522027F for ; Mon, 12 Aug 2013 04:13:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752637Ab3HLENX (ORCPT ); Mon, 12 Aug 2013 00:13:23 -0400 Received: from mail-pd0-f180.google.com ([209.85.192.180]:59033 "EHLO mail-pd0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752305Ab3HLENW (ORCPT ); Mon, 12 Aug 2013 00:13:22 -0400 Received: by mail-pd0-f180.google.com with SMTP id y10so2857196pdj.39 for ; Sun, 11 Aug 2013 21:13:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pro8AdxZ9SdiX2DFAgFXKV7OI/MeHrCNYRT4kWiS5mU=; b=lEJy5yUc5S4F4H/TzzoN8KnmO+Ohd/Jz2Qp2jdBMctjgI9/6Rr3gs0XTbhdRTtXmps li1kSruikQMiuRTthgjY4dQrN4Go2aeoRk+dyXMo/Ui4AmkiDJvsHammZrt16frdMEVy rqD8B051ad4ypFn/qeftRx8pju80NsmD6bHWjlswNzIrZ97jrq55lT/ZxLsBya2s7d4z TLoM1sCPkHRX4BqQmjNP+/Ae1A3OkZg63q7dbF9+n0FPyvQyn1uzdWu2WG9E223ZAZsg H8ZsQ9KDccARvWKekTCEOFB8PmkfMI7AGbANfJj5JBf1Bk0zRrUuU1GN0xZhbBbhoy+A juHQ== X-Gm-Message-State: ALoCoQkY+zXXa+lxsoGukIEWD4Ya5XUidcewID19OiDV/I0HKUrwCriysR/maGr1ljSt1nNG6yiR X-Received: by 10.66.25.205 with SMTP id e13mr22608265pag.180.1376280801950; Sun, 11 Aug 2013 21:13:21 -0700 (PDT) Received: from localhost.localdomain (c-67-169-183-77.hsd1.ca.comcast.net. [67.169.183.77]) by mx.google.com with ESMTPSA id nj9sm34355902pbc.13.2013.08.11.21.13.20 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 11 Aug 2013 21:13:21 -0700 (PDT) From: Christoffer Dall To: Paolo Bonzini , Gleb Natapov Cc: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, linaro-kernel@lists.linaro.org, patches@linaro.org, Christoffer Dall Subject: [PATCH 2/4] ARM: KVM: Fix unaligned unmap_range leak Date: Sun, 11 Aug 2013 21:12:59 -0700 Message-Id: <1376280781-6539-3-git-send-email-christoffer.dall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1376280781-6539-1-git-send-email-christoffer.dall@linaro.org> References: <1376280781-6539-1-git-send-email-christoffer.dall@linaro.org> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The unmap_range function did not properly cover the case when the start address was not aligned to PMD_SIZE or PUD_SIZE and an entire pte table or pmd table was cleared, causing us to leak memory when incrementing the addr. The fix is to always move onto the next page table entry boundary instead of adding the full size of the VA range covered by the corresponding table level entry. Acked-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm/kvm/mmu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index ca6bea4..80a83ec 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -132,37 +132,37 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, pmd_t *pmd; pte_t *pte; unsigned long long addr = start, end = start + size; - u64 range; + u64 next; while (addr < end) { pgd = pgdp + pgd_index(addr); pud = pud_offset(pgd, addr); if (pud_none(*pud)) { - addr += PUD_SIZE; + addr = pud_addr_end(addr, end); continue; } pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) { - addr += PMD_SIZE; + addr = pmd_addr_end(addr, end); continue; } pte = pte_offset_kernel(pmd, addr); clear_pte_entry(kvm, pte, addr); - range = PAGE_SIZE; + next = addr + PAGE_SIZE; /* If we emptied the pte, walk back up the ladder */ if (pte_empty(pte)) { clear_pmd_entry(kvm, pmd, addr); - range = PMD_SIZE; + next = pmd_addr_end(addr, end); if (pmd_empty(pmd)) { clear_pud_entry(kvm, pud, addr); - range = PUD_SIZE; + next = pud_addr_end(addr, end); } } - addr += range; + addr = next; } }