From patchwork Tue Jul 25 21:11:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John David Anglin X-Patchwork-Id: 9863701 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 50CFF601A1 for ; Tue, 25 Jul 2017 21:11:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 367D72871B for ; Tue, 25 Jul 2017 21:11:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2B3EB2871D; Tue, 25 Jul 2017 21:11:34 +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=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_TVD_MIME_EPI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 90FE828735 for ; Tue, 25 Jul 2017 21:11:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752186AbdGYVLc (ORCPT ); Tue, 25 Jul 2017 17:11:32 -0400 Received: from simcoe207srvr.owm.bell.net ([184.150.200.207]:60427 "EHLO torfep01.bell.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752145AbdGYVL3 (ORCPT ); Tue, 25 Jul 2017 17:11:29 -0400 Received: from bell.net torfep01 184.150.200.158 by torfep01.bell.net with ESMTP id <20170725211127.BYLH14026.torfep01.bell.net@torspm02.bell.net> for ; Tue, 25 Jul 2017 17:11:27 -0400 Received: from [192.168.2.25] (really [70.31.74.123]) by torspm02.bell.net with ESMTP id <20170725211127.MQCR23640.torspm02.bell.net@[192.168.2.25]>; Tue, 25 Jul 2017 17:11:27 -0400 From: John David Anglin Mime-Version: 1.0 (Apple Message framework v1085) Date: Tue, 25 Jul 2017 17:11:26 -0400 Subject: [PATCH] parisc: Prevent TLB speculation on flushed pages on CPUs that only support equivalent aliases Cc: Helge Deller , James Bottomley To: Parisc List Message-Id: <71EB19D6-E071-42AE-A338-A0D600EEE627@bell.net> X-Mailer: Apple Mail (2.1085) X-Cloudmark-Analysis: v=2.2 cv=ActeJzfG c=1 sm=0 tr=0 a=CP4CeFkTTpGPfaygvaSIJA==:17 a=G3gG6ho9WtcA:10 a=y7chnbD_AAAA:8 a=DLV23wSTzonCuWxrG70A:9 a=CjuIK1q_8ugA:10 a=CxMdbk7o4uYj1uhPzOUA:9 a=Ld372NDzu18A:10 a=FBHGMhGWAAAA:8 a=CTwWI_8SlGQyalyz8_QA:9 a=ATlVsGG5QSsA:10 a=lhz_U0R9uZa6jetOpQ8g:22 a=9gvnlMMaQFpL9xblJ6ne:22 Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Helge noticed that we flush the TLB page in flush_cache_page but not in flush_cache_range or flush_cache_mm. For a long time, we have had random segmentation faults building packages on machines with PA8800/8900 processors. These machines only support equivalent aliases. We don't see these faults on machines that don't require strict coherency. So, it appears TLB speculation sometimes leads to cache corruption on machines that require coherency. This patch adds TLB flushes to flush_cache_range and flush_cache_mm when coherency is required. We only flush the TLB in flush_cache_page when coherency is required. The patch also optimizes flush_cache_range. It turns out we always have the right context to use flush_user_dcache_range_asm and flush_user_icache_range_asm. The patch has been tested for some time on rp3440, rp3410 and A500-44. It's been boot tested on c8000. No random segmentation faults were observed during testing. Signed-off-by: John David Anglin --- John David Anglin dave.anglin@bell.net diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index c32a09095216..85a92db70afc 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -539,6 +539,10 @@ void flush_cache_mm(struct mm_struct *mm) struct vm_area_struct *vma; pgd_t *pgd; + /* Flush the TLB to avoid speculation if coherency is required. */ + if (parisc_requires_coherency()) + flush_tlb_all(); + /* Flushing the whole cache on each cpu takes forever on rp3440, etc. So, avoid it if the mm isn't too big. */ if (mm_total_size(mm) >= parisc_cache_flush_threshold) { @@ -577,33 +581,22 @@ void flush_cache_mm(struct mm_struct *mm) void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - unsigned long addr; - pgd_t *pgd; - BUG_ON(!vma->vm_mm->context); + /* Flush the TLB to avoid speculation if coherency is required. */ + if (parisc_requires_coherency()) + flush_tlb_range(vma, start, end); + if ((end - start) >= parisc_cache_flush_threshold) { flush_cache_all(); return; } - if (vma->vm_mm->context == mfsp(3)) { - flush_user_dcache_range_asm(start, end); - if (vma->vm_flags & VM_EXEC) - flush_user_icache_range_asm(start, end); - return; - } + BUG_ON(vma->vm_mm->context != mfsp(3)); - pgd = vma->vm_mm->pgd; - for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) { - unsigned long pfn; - pte_t *ptep = get_ptep(pgd, addr); - if (!ptep) - continue; - pfn = pte_pfn(*ptep); - if (pfn_valid(pfn)) - __flush_cache_page(vma, addr, PFN_PHYS(pfn)); - } + flush_user_dcache_range_asm(start, end); + if (vma->vm_flags & VM_EXEC) + flush_user_icache_range_asm(start, end); } void @@ -612,7 +605,8 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long BUG_ON(!vma->vm_mm->context); if (pfn_valid(pfn)) { - flush_tlb_page(vma, vmaddr); + if (parisc_requires_coherency()) + flush_tlb_page(vma, vmaddr); __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); } }