[PATCH v4 4/8] x86/mm/pat: use early_param_off() and redefine pat_enabled()

From: Luis R. Rodriguez
Date: Wed Apr 29 2015 - 17:57:00 EST


From: "Luis R. Rodriguez" <mcgrof@xxxxxxxx>

We use pat_enabled on x86 specific code to see if PAT is
enabled or not, we however are granting full access to the
variable even though readers do not need to set it.

This uses the early_param_off() to simplify the definition of
the old pat_enabled under a new static variable __pat_enabled,
for access to see if its enabled / disabled folks can just use
pat_enabled() now. Code that set this is purely internal to
pat.c. Apart from the early parameter to disable it we also have
a few cases that disable it later, these were wrapped under
and ifdef but since that code cannot run unless PAT was enabled
its not required to wrap it with ifdefs.

Cc: Andy Walls <awalls@xxxxxxxxxxxxxxxx>
Cc: Doug Ledford <dledford@xxxxxxxxxx>
Cc: Andy Lutomirski <luto@xxxxxxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Juergen Gross <jgross@xxxxxxxx>
Cc: Daniel Vetter <daniel.vetter@xxxxxxxx>
Cc: Dave Airlie <airlied@xxxxxxxxxx>
Cc: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxx>
Cc: Michael S. Tsirkin <mst@xxxxxxxxxx>
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: x86@xxxxxxxxxx
Signed-off-by: Luis R. Rodriguez <mcgrof@xxxxxxxx>
---
arch/x86/include/asm/pat.h | 7 +------
arch/x86/kernel/cpu/mtrr/main.c | 2 +-
arch/x86/mm/iomap_32.c | 2 +-
arch/x86/mm/ioremap.c | 4 ++--
arch/x86/mm/pageattr.c | 2 +-
arch/x86/mm/pat.c | 38 ++++++++++++++------------------------
arch/x86/pci/i386.c | 6 +++---
7 files changed, 23 insertions(+), 38 deletions(-)

diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
index 91bc4ba..cdcff7f 100644
--- a/arch/x86/include/asm/pat.h
+++ b/arch/x86/include/asm/pat.h
@@ -4,12 +4,7 @@
#include <linux/types.h>
#include <asm/pgtable_types.h>

-#ifdef CONFIG_X86_PAT
-extern int pat_enabled;
-#else
-static const int pat_enabled;
-#endif
-
+bool pat_enabled(void);
extern void pat_init(void);
void pat_init_cache_modes(void);

diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index bfef424..f094d36 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -556,7 +556,7 @@ int arch_phys_wc_add(unsigned long base, unsigned long size)
{
int ret;

- if (pat_enabled || !mtrr_enabled)
+ if (pat_enabled() || !mtrr_enabled)
return 0; /* Success! (We don't need to do anything.) */

ret = mtrr_add(base, size, MTRR_TYPE_WRCOMB, true);
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index 9ca35fc..3a2ec87 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -82,7 +82,7 @@ iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot)
* MTRR is UC or WC. UC_MINUS gets the real intention, of the
* user, which is "WC if the MTRR is WC, UC if you can't do that."
*/
- if (!pat_enabled && pgprot_val(prot) ==
+ if (!pat_enabled() && pgprot_val(prot) ==
(__PAGE_KERNEL | cachemode2protval(_PAGE_CACHE_MODE_WC)))
prot = __pgprot(__PAGE_KERNEL |
cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS));
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index a493bb8..82d63ed 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -234,7 +234,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
{
/*
* Ideally, this should be:
- * pat_enabled ? _PAGE_CACHE_MODE_UC : _PAGE_CACHE_MODE_UC_MINUS;
+ * pat_enabled() ? _PAGE_CACHE_MODE_UC : _PAGE_CACHE_MODE_UC_MINUS;
*
* Till we fix all X drivers to use ioremap_wc(), we will use
* UC MINUS. Drivers that are certain they need or can already
@@ -292,7 +292,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
*/
void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
{
- if (pat_enabled)
+ if (pat_enabled())
return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
__builtin_return_address(0));
else
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 49660c0..0aa8dd8 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -1574,7 +1574,7 @@ int set_memory_wc(unsigned long addr, int numpages)
{
int ret;

- if (!pat_enabled)
+ if (!pat_enabled())
return set_memory_uc(addr, numpages);

ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 917155d..b1f9a67 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -33,28 +33,18 @@
#include "pat_internal.h"
#include "mm_internal.h"

-#ifdef CONFIG_X86_PAT
-int __read_mostly pat_enabled = 1;
+static early_param_off("nopat", __pat_enabled, CONFIG_X86_PAT);

static inline void pat_disable(const char *reason)
{
- pat_enabled = 0;
+ __pat_enabled = 0;
pr_info("%s\n", reason);
}

-static int __init nopat(char *str)
-{
- pat_disable("PAT support disabled.");
- return 0;
-}
-early_param("nopat", nopat);
-#else
-static inline void pat_disable(const char *reason)
+bool pat_enabled(void)
{
- (void)reason;
+ return !!__pat_enabled;
}
-#endif
-

int pat_debug_enable;

@@ -198,7 +188,7 @@ void pat_init(void)
u64 pat;
bool boot_cpu = !boot_pat_state;

- if (!pat_enabled)
+ if (!pat_enabled())
return;

if (!cpu_has_pat) {
@@ -399,7 +389,7 @@ int reserve_memtype(u64 start, u64 end, enum page_cache_mode req_type,

BUG_ON(start >= end); /* end is exclusive */

- if (!pat_enabled) {
+ if (!pat_enabled()) {
/* This is identical to page table setting without PAT */
if (new_type) {
if (req_type == _PAGE_CACHE_MODE_WC)
@@ -474,7 +464,7 @@ int free_memtype(u64 start, u64 end)
int is_range_ram;
struct memtype *entry;

- if (!pat_enabled)
+ if (!pat_enabled())
return 0;

/* Low ISA region is always mapped WB. No need to track */
@@ -623,7 +613,7 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
u64 to = from + size;
u64 cursor = from;

- if (!pat_enabled)
+ if (!pat_enabled())
return 1;

while (cursor < to) {
@@ -659,7 +649,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
* caching for the high addresses through the KEN pin, but
* we maintain the tradition of paranoia in this code.
*/
- if (!pat_enabled &&
+ if (!pat_enabled() &&
!(boot_cpu_has(X86_FEATURE_MTRR) ||
boot_cpu_has(X86_FEATURE_K6_MTRR) ||
boot_cpu_has(X86_FEATURE_CYRIX_ARR) ||
@@ -728,7 +718,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
* the type requested matches the type of first page in the range.
*/
if (is_ram) {
- if (!pat_enabled)
+ if (!pat_enabled())
return 0;

pcm = lookup_memtype(paddr);
@@ -843,7 +833,7 @@ int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
return ret;
}

- if (!pat_enabled)
+ if (!pat_enabled())
return 0;

/*
@@ -871,7 +861,7 @@ int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
{
enum page_cache_mode pcm;

- if (!pat_enabled)
+ if (!pat_enabled())
return 0;

/* Set prot based on lookup */
@@ -912,7 +902,7 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,

pgprot_t pgprot_writecombine(pgprot_t prot)
{
- if (pat_enabled)
+ if (pat_enabled())
return __pgprot(pgprot_val(prot) |
cachemode2protval(_PAGE_CACHE_MODE_WC));
else
@@ -995,7 +985,7 @@ static const struct file_operations memtype_fops = {

static int __init pat_memtype_list_init(void)
{
- if (pat_enabled) {
+ if (pat_enabled()) {
debugfs_create_file("pat_memtype_list", S_IRUSR,
arch_debugfs_dir, NULL, &memtype_fops);
}
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 349c0d3..0a9f2ca 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -429,12 +429,12 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
* Caller can followup with UC MINUS request and add a WC mtrr if there
* is a free mtrr slot.
*/
- if (!pat_enabled && write_combine)
+ if (!pat_enabled() && write_combine)
return -EINVAL;

- if (pat_enabled && write_combine)
+ if (pat_enabled() && write_combine)
prot |= cachemode2protval(_PAGE_CACHE_MODE_WC);
- else if (pat_enabled || boot_cpu_data.x86 > 3)
+ else if (pat_enabled() || boot_cpu_data.x86 > 3)
/*
* ioremap() and ioremap_nocache() defaults to UC MINUS for now.
* To avoid attribute conflicts, request UC MINUS here
--
2.3.2.209.gd67f9d5.dirty

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/