From patchwork Sun Oct 14 17:42:22 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Yan-Pai Chen X-Patchwork-Id: 1591411 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 2A7D2E00AD for ; Sun, 14 Oct 2012 17:51:48 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TNSJi-0003Pa-3z; Sun, 14 Oct 2012 17:49:34 +0000 Received: from mail-pb0-f49.google.com ([209.85.160.49]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TNSJd-0003PM-Mg for linux-arm-kernel@lists.infradead.org; Sun, 14 Oct 2012 17:49:30 +0000 Received: by mail-pb0-f49.google.com with SMTP id xa7so4461107pbc.36 for ; Sun, 14 Oct 2012 10:49:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer; bh=xqfcwUOK1veS5XeylkCTTwMRNXGD0BZ4yFbOUchfY1A=; b=gccCb1ePRjPhXlN6bIva3EtbcsEd5YI2XeVRcVRy7S0rJnNiLQNdW8nxoMyRFfLnfP /owmlqr9NH7SaYq29wB3XA3S1V5BfqYA2plWui5wEfZujromHZQtrgk/tK2ZcTcUKE8d tuP9FP5XhG5VrEbvProbSiFKLZ8ZJIq1Js3BrIRFWm6A5G92XNf+Ui7mrsMa27HWZICU g1eZEF+lNnxhnGIApXyonJBVyO9lOf6jaYgEzs/6hAaXbCbstIYPCHL2BSRENRNGwMON /tFIsIJaol2QXPd5QJQlX/2c7AvNgYj0e9hsamkpU1mbF906o/CTZzx2vb7IOQElFaEq 7UYg== Received: by 10.68.204.2 with SMTP id ku2mr30798945pbc.59.1350236558521; Sun, 14 Oct 2012 10:42:38 -0700 (PDT) Received: from localhost.localdomain (220-134-96-131.HINET-IP.hinet.net. [220.134.96.131]) by mx.google.com with ESMTPS id x6sm7715934pav.29.2012.10.14.10.42.31 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 14 Oct 2012 10:42:37 -0700 (PDT) From: Andrew Yan-Pai Chen To: linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH v2] prevent top pte being overwritten before flushing Date: Mon, 15 Oct 2012 01:42:22 +0800 Message-Id: <1350236542-96465-1-git-send-email-yanpai.chen@gmail.com> X-Mailer: git-send-email 1.7.12.3 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (yanpai.chen[at]gmail.com) -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.160.49 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: catalin.marinas@arm.com, Yan-Pai Chen , linux@arm.linux.org.uk, kernel.jason@gmail.com, JasonLin X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Yan-Pai Chen Since flush_pfn_alias() is preemptible, it is possible to be preempted just after set_top_pte() is done. If the process which preempts the previous happened to invoke flush_pfn_alias() with the same colour vaddr as that of the previous, the same top pte will be overwritten. When switching back to the previous, it attempts to flush cache lines with incorrect mapping. Then no lines (or wrong lines) will be flushed because of the nature of vipt caches. flush_icache_alias() has the same problem as well. However, as it could be called in SMP setups, we prevent concurrent overwrites of top pte by having a lock on it. Signed-off-by: JasonLin Signed-off-by: Yan-Pai Chen --- arch/arm/mm/flush.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 40ca11e..b6510f4 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -22,11 +23,15 @@ #ifdef CONFIG_CPU_CACHE_VIPT +static DEFINE_RAW_SPINLOCK(flush_lock); + +/* Beware that this function is not to be called for SMP setups. */ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) { unsigned long to = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); const int zero = 0; + preempt_disable(); set_top_pte(to, pfn_pte(pfn, PAGE_KERNEL)); asm( "mcrr p15, 0, %1, %0, c14\n" @@ -34,6 +39,8 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) : : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero) : "cc"); + + preempt_enable(); } static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len) @@ -42,9 +49,13 @@ static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned unsigned long offset = vaddr & (PAGE_SIZE - 1); unsigned long to; + raw_spin_lock(&flush_lock); + set_top_pte(va, pfn_pte(pfn, PAGE_KERNEL)); to = va + offset; flush_icache_range(to, to + len); + + raw_spin_unlock(&flush_lock); } void flush_cache_mm(struct mm_struct *mm)