From patchwork Fri Mar 20 23:17:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luis R. Rodriguez" X-Patchwork-Id: 6061701 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9D7279F399 for ; Fri, 20 Mar 2015 23:34:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9DF7920522 for ; Fri, 20 Mar 2015 23:34:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8FAB320519 for ; Fri, 20 Mar 2015 23:34:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752625AbbCTXeN (ORCPT ); Fri, 20 Mar 2015 19:34:13 -0400 Received: from mail-pa0-f43.google.com ([209.85.220.43]:35584 "EHLO mail-pa0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752113AbbCTXeI (ORCPT ); Fri, 20 Mar 2015 19:34:08 -0400 Received: by pagj4 with SMTP id j4so31912532pag.2; Fri, 20 Mar 2015 16:34:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=eybm+vfBTHEZQRr1tg6UjOR731BPIEkr+pSq4Flcwss=; b=Pr6hL1oqP5MtovQoRZ2P5xdy2iNSYpAy11MYo9+8EQab9fJTAHLfHB991xX7M1wOR1 S33TEy9gctMEv2E0/dh67rLdemj1vJiyBiPeKyUKab5IDbUi+TfPZMFeAh1AQA9Uf1ev ePt3KL09d8gop/GILLUqcdtqTbs2fcxSAo6BDMSdFUEPXWK+DjJa1jsI0kU25JNnZJ8s WyXuCRVKkAKvmtGQmi7RdSSU0tcfueM6ZUiC0iPPZ41++CEe5Qx9AjYkHQ/Qqxtq8CWd hsrltXSDDuKlrppw6PXcn65b75RYJDbA67sV/GOwxqIsWRHLALnoZRGKL82yBk9i0R3k /uHA== X-Received: by 10.67.10.47 with SMTP id dx15mr194689176pad.139.1426894447886; Fri, 20 Mar 2015 16:34:07 -0700 (PDT) Received: from mcgrof@gmail.com (c-98-234-145-61.hsd1.ca.comcast.net. [98.234.145.61]) by mx.google.com with ESMTPSA id qv9sm9826711pab.27.2015.03.20.16.34.04 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 20 Mar 2015 16:34:06 -0700 (PDT) Received: by mcgrof@gmail.com (sSMTP sendmail emulation); Fri, 20 Mar 2015 16:31:55 -0700 From: "Luis R. Rodriguez" To: luto@amacapital.net, mingo@redhat.com, tglx@linutronix.de, hpa@zytor.com, jgross@suse.com, JBeulich@suse.com, bp@suse.de, suresh.b.siddha@intel.com, venkatesh.pallipadi@intel.com, airlied@redhat.com Cc: linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org, x86@kernel.org, xen-devel@lists.xenproject.org, "Luis R. Rodriguez" , Ingo Molnar , Daniel Vetter , Antonino Daplas , Jean-Christophe Plagniol-Villard , Tomi Valkeinen Subject: [PATCH v1 06/47] mtrr: add __arch_phys_wc_add() Date: Fri, 20 Mar 2015 16:17:56 -0700 Message-Id: <1426893517-2511-7-git-send-email-mcgrof@do-not-panic.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1426893517-2511-1-git-send-email-mcgrof@do-not-panic.com> References: <1426893517-2511-1-git-send-email-mcgrof@do-not-panic.com> Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable 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 From: "Luis R. Rodriguez" Ideally on systems using PAT we can expect a swift transition away from MTRR. There can be a few exceptions to this, one is where device drivers are known to exist on PATs with errata, another situation is observed on old device drivers where devices had combined MMIO register access with whatever area they typically later wanted to end up using MTRR for on the same PCI BAR. This situation can still be addressed by splitting up ioremap'd PCI BAR into two ioremap'd calls, one for MMIO registers, and another for whatever is desirable for write-combining -- in order to accomplish this though quite a bit of driver restructuring is required. Device drivers which are known to require large amount of re-work in order to split ioremap'd areas can use __arch_phys_wc_add() to avoid regressions when PAT is enabled. For a good example driver where things are neatly split up on a PCI BAR refer the infiniband qib driver. For a good example of a driver where good amount of work is required refer to the infiniband ipath driver. This is *only* a transitive API -- and as such no new drivers are ever expected to use this. Cc: Suresh Siddha Cc: Venkatesh Pallipadi Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Juergen Gross Cc: Daniel Vetter Cc: Andy Lutomirski Cc: Dave Airlie Cc: Antonino Daplas Cc: Jean-Christophe Plagniol-Villard Cc: Tomi Valkeinen Cc: linux-fbdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Luis R. Rodriguez --- arch/x86/include/asm/io.h | 4 ++++ arch/x86/kernel/cpu/mtrr/main.c | 36 +++++++++++++++++++++++++++++------- include/linux/io.h | 4 ++++ 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 34a5b93..a144d05 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -338,6 +338,10 @@ extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, #define IO_SPACE_LIMIT 0xffff #ifdef CONFIG_MTRR +extern int __must_check __arch_phys_wc_add(unsigned long base, + unsigned long size); +#define __arch_phys_wc_add __arch_phys_wc_add + extern int __must_check arch_phys_wc_add(unsigned long base, unsigned long size); extern void arch_phys_wc_del(int handle); diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 7db9c47..5ae830b 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -538,23 +538,24 @@ int mtrr_del(int reg, unsigned long base, unsigned long size) EXPORT_SYMBOL(mtrr_del); /** - * arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable + * __arch_phys_wc_add - add a WC MTRR even if PAT is available * @base: Physical base address * @size: Size of region * - * If PAT is available, this does nothing. If PAT is unavailable, it - * attempts to add a WC MTRR covering size bytes starting at base and - * logs an error if this fails. + * We typically do not want to use MTRR if PAT is available but there + * are some drivers which require significant work to get this to work + * properly. This call should only be used by those drivers where it is + * clear that hard work is required to modify them to use arch_phys_wc_add() * * Drivers must store the return value to pass to mtrr_del_wc_if_needed, * but drivers should not try to interpret that return value. */ -int arch_phys_wc_add(unsigned long base, unsigned long size) +int __arch_phys_wc_add(unsigned long base, unsigned long size) { int ret; - if (pat_enabled || !mtrr_enabled) - return 0; /* Success! (We don't need to do anything.) */ + if (!mtrr_enabled) + return 0; ret = mtrr_add(base, size, MTRR_TYPE_WRCOMB, true); if (ret < 0) { @@ -564,6 +565,27 @@ int arch_phys_wc_add(unsigned long base, unsigned long size) } return ret + MTRR_TO_PHYS_WC_OFFSET; } +EXPORT_SYMBOL_GPL(__arch_phys_wc_add); + +/** + * arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable + * @base: Physical base address + * @size: Size of region + * + * If PAT is available, this does nothing. If PAT is unavailable, it + * attempts to add a WC MTRR covering size bytes starting at base and + * logs an error if this fails. + * + * Drivers must store the return value to pass to mtrr_del_wc_if_needed, + * but drivers should not try to interpret that return value. + */ +int arch_phys_wc_add(unsigned long base, unsigned long size) +{ + if (pat_enabled || !mtrr_enabled) + return 0; /* Success! (We don't need to do anything.) */ + + return __arch_phys_wc_add(base, size); +} EXPORT_SYMBOL(arch_phys_wc_add); /* diff --git a/include/linux/io.h b/include/linux/io.h index 91101a1..ecc51c3 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -111,6 +111,10 @@ static inline void arch_phys_wc_del(int handle) } #define arch_phys_wc_add arch_phys_wc_add +#ifndef __arch_phys_wc_add +#define __arch_phys_wc_add arch_phys_wc_add +#endif + #endif #endif /* _LINUX_IO_H */