From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752084AbbCKVFs (ORCPT ); Wed, 11 Mar 2015 17:05:48 -0400 Received: from mga11.intel.com ([192.55.52.93]:60383 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751384AbbCKVFr (ORCPT ); Wed, 11 Mar 2015 17:05:47 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,384,1422950400"; d="scan'208";a="663942546" From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , x86@kernel.org, Dan Williams , Borislav Petkov Subject: [PATCH] x86: improve algorithm in clflush_cache_range Date: Wed, 11 Mar 2015 15:04:59 -0600 Message-Id: <1426107899-27933-1-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 1.9.3 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The current algorithm used in clflush_cache_range() can cause the last cache line of the buffer to be flushed twice. Fix that algorithm so that each cache line will only be flushed once, and remove arithmetic on void pointers. Void pointer arithmetic is allowed by GCC extensions, but isn't part of the base C standards. Signed-off-by: Ross Zwisler Reported-by: H. Peter Anvin Cc: H. Peter Anvin Cc: Thomas Gleixner Cc: Ingo Molnar Cc: x86@kernel.org Cc: Dan Williams Cc: Borislav Petkov --- arch/x86/mm/pageattr.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index ae242a7c11c7..b75ecac859f2 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -131,16 +131,15 @@ within(unsigned long addr, unsigned long start, unsigned long end) */ void clflush_cache_range(void *vaddr, unsigned int size) { - void *vend = vaddr + size - 1; + unsigned long clflush_mask = boot_cpu_data.x86_clflush_size - 1; + char *vend = (char *)vaddr + size; + char *p; mb(); - for (; vaddr < vend; vaddr += boot_cpu_data.x86_clflush_size) - clflushopt(vaddr); - /* - * Flush any possible final partial cacheline: - */ - clflushopt(vend); + for (p = (char *)((unsigned long)vaddr & ~clflush_mask); + p < vend; p += boot_cpu_data.x86_clflush_size) + clflushopt(p); mb(); } -- 1.9.3