Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1679643 > unrolled thread
| Started by | Mikulas Patocka <mpatocka@redhat.com> |
|---|---|
| First post | 2017-07-03 07:10 +0200 |
| Last post | 2017-07-05 09:20 +0200 |
| Articles | 5 — 3 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH v2] X86: don't report PAT on CPUs that don't support it Mikulas Patocka <mpatocka@redhat.com> - 2017-07-03 07:10 +0200
Re: [PATCH v2] X86: don't report PAT on CPUs that don't support it Thomas Gleixner <tglx@linutronix.de> - 2017-07-04 15:50 +0200
Re: [PATCH v2] X86: don't report PAT on CPUs that don't support it Thomas Gleixner <tglx@linutronix.de> - 2017-07-04 15:50 +0200
[PATCH v3] X86: don't report PAT on CPUs that don't support it Mikulas Patocka <mpatocka@redhat.com> - 2017-07-05 01:10 +0200
[tip:x86/urgent] x86/mm/pat: Don't report PAT on CPUs that don't support it tip-bot for Mikulas Patocka <tipbot@zytor.com> - 2017-07-05 09:20 +0200
| From | Mikulas Patocka <mpatocka@redhat.com> |
|---|---|
| Date | 2017-07-03 07:10 +0200 |
| Subject | Re: [PATCH v2] X86: don't report PAT on CPUs that don't support it |
| Message-ID | <tZ1Mu-4SF-7@gated-at.bofh.it> |
On Tue, 6 Jun 2017, Mikulas Patocka wrote:
> Hi
>
> Here I send the second version of the patch. It drops the change from
> boot_cpu_has(X86_FEATURE_PAT) to this_cpu_has(X86_FEATURE_PAT) (that
> caused kernel to be unbootable for some people).
>
> Another change is that setup_arch() calls init_cache_modes() if PAT is
> disabled, so that init_cache_modes() is always called.
>
> Mikulas
Is there any progress with this patch? Will you accept it or do you want
some changes to it?
> From: Mikulas Patocka <mpatocka@redhat.com>
>
> In the file arch/x86/mm/pat.c, there's a variable __pat_enabled. The
> variable is set to 1 by default and the function pat_init() sets
> __pat_enabled to 0 if the CPU doesn't support PAT.
>
> However, on AMD K6-3 CPU, the processor initialization code never calls
> pat_init() and so __pat_enabled stays 1 and the function pat_enabled()
> returns true, even though the K6-3 CPU doesn't support PAT.
>
> The result of this bug is that this warning is produced when attemting to
> start the Xserver and the Xserver doesn't start (fork() returns ENOMEM).
> Another symptom of this bug is that the framebuffer driver doesn't set the
> K6-3 MTRR registers.
>
> This patch changes pat_enabled() so that it returns true only if pat
> initialization was actually done.
>
> As Andy Lutomirski suggested, we also need to call init_cache_modes() if
> pat was not initialized, so we call it after mtrr_bp_init()
> (mtrr_bp_init() would or wouldn't call pat_init()). Note that
> init_cache_modes() detects if it was called more than once and does
> nothing in that case.
>
> x86/PAT: Xorg:3891 map pfn expected mapping type uncached-minus for [mem 0xe4000000-0xe5ffffff], got write-combining
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 3891 at arch/x86/mm/pat.c:1020 untrack_pfn+0x5c/0x9f
> Modules linked in: blowfish_generic blowfish_common cbc dm_crypt dm_loop msr configfs cpufreq_userspace cpufreq_powersave cpufreq_ondemand cpufreq_conservative ext4 crc16 jbd2 mbcache hpfs nls_cp852 msdos fat matroxfb_base matroxfb_g450 matroxfb_accel cfbfillrect cfbimgblt cfbcopyarea matroxfb_DAC1064 g450_pll matroxfb_misc floppy snd_usb_audio snd_hwdep snd_usbmidi_lib snd_seq_midi snd_seq_midi_event snd_rawmidi snd_pcm snd_seq snd_seq_device snd_timer hid_generic snd usbhid hid soundcore powernow_k6 pcspkr evdev e1000 ehci_pci uhci_hcd ehci_hcd usbcore usb_common dm_mod pata_it821x unix
> CPU: 0 PID: 3891 Comm: Xorg Not tainted 4.11.0-rc6-test+ #35
> Hardware name: System Manufacturer Product Name/VA-503A, BIOS 4.51 PG 08/02/00
> Call Trace:
> ? __warn+0xab/0xc0
> ? untrack_pfn+0x5c/0x9f
> ? warn_slowpath_null+0xf/0x13
> ? untrack_pfn+0x5c/0x9f
> ? unmap_single_vma+0x43/0x66
> ? unmap_vmas+0x24/0x30
> ? exit_mmap+0x3c/0xa5
> ? __mmput+0xf/0x76
> ? copy_process.part.76+0xb43/0x1129
> ? _do_fork+0x96/0x177
> ? do_int80_syscall_32+0x3e/0x4c
> ? entry_INT80_32+0x2a/0x2a
> ---[ end trace 8726f9d9fa90d702 ]---
> x86/PAT: Xorg:3891 map pfn expected mapping type uncached-minus for [mem 0xe4000000-0xe5ffffff], got write-combining
>
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
> Cc: stable@vger.kernel.org # v4.2+
>
> ---
> arch/x86/include/asm/pat.h | 1 +
> arch/x86/kernel/setup.c | 2 ++
> arch/x86/mm/pat.c | 10 ++++++----
> 3 files changed, 9 insertions(+), 4 deletions(-)
>
> Index: linux-stable/arch/x86/mm/pat.c
> ===================================================================
> --- linux-stable.orig/arch/x86/mm/pat.c
> +++ linux-stable/arch/x86/mm/pat.c
> @@ -40,7 +40,6 @@
> static bool boot_cpu_done;
>
> static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
> -static void init_cache_modes(void);
>
> void pat_disable(const char *reason)
> {
> @@ -65,9 +64,11 @@ static int __init nopat(char *str)
> }
> early_param("nopat", nopat);
>
> +static bool __read_mostly __pat_initialized = false;
> +
> bool pat_enabled(void)
> {
> - return !!__pat_enabled;
> + return __pat_initialized;
> }
> EXPORT_SYMBOL_GPL(pat_enabled);
>
> @@ -225,6 +226,7 @@ static void pat_bsp_init(u64 pat)
> }
>
> wrmsrl(MSR_IA32_CR_PAT, pat);
> + __pat_initialized = true;
>
> __init_cache_modes(pat);
> }
> @@ -242,7 +244,7 @@ static void pat_ap_init(u64 pat)
> wrmsrl(MSR_IA32_CR_PAT, pat);
> }
>
> -static void init_cache_modes(void)
> +void init_cache_modes(void)
> {
> u64 pat = 0;
> static int init_cm_done;
> @@ -306,7 +308,7 @@ void pat_init(void)
> u64 pat;
> struct cpuinfo_x86 *c = &boot_cpu_data;
>
> - if (!pat_enabled()) {
> + if (!__pat_enabled) {
> init_cache_modes();
> return;
> }
> Index: linux-stable/arch/x86/include/asm/pat.h
> ===================================================================
> --- linux-stable.orig/arch/x86/include/asm/pat.h
> +++ linux-stable/arch/x86/include/asm/pat.h
> @@ -7,6 +7,7 @@
> bool pat_enabled(void);
> void pat_disable(const char *reason);
> extern void pat_init(void);
> +extern void init_cache_modes(void);
>
> extern int reserve_memtype(u64 start, u64 end,
> enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);
> Index: linux-stable/arch/x86/kernel/setup.c
> ===================================================================
> --- linux-stable.orig/arch/x86/kernel/setup.c
> +++ linux-stable/arch/x86/kernel/setup.c
> @@ -1070,6 +1070,8 @@ void __init setup_arch(char **cmdline_p)
>
> /* update e820 for memory not covered by WB MTRRs */
> mtrr_bp_init();
> + if (!pat_enabled())
> + init_cache_modes();
> if (mtrr_trim_uncached_memory(max_pfn))
> max_pfn = e820__end_of_ram_pfn();
>
>
[toc] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-07-04 15:50 +0200 |
| Message-ID | <tZwnf-pQ-1@gated-at.bofh.it> |
| In reply to | #1679643 |
On Tue, 4 Jul 2017, Thomas Gleixner wrote: > wrmsrl(MSR_IA32_CR_PAT, pat); > + __pat_initialized = true; That should be > + pat_initialized = true; of course.
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-07-04 15:50 +0200 |
| Message-ID | <tZwng-pQ-3@gated-at.bofh.it> |
| In reply to | #1679643 |
On Mon, 3 Jul 2017, Mikulas Patocka wrote:
> Is there any progress with this patch? Will you accept it or do you want
> some changes to it?
Aside of the unparseable changelog, that patch is mostly duct tape.
1) __pat_enabled should be renamed to pat_disabled, as that is the actual
purpose of that variable
2) Making the call to init_cache_modes() conditional in setup_arch() is
pointless. init_cache_modes() has it's own protection against multiple
invocations.
3) It adds yet another invocation of init_cache_modes() instead of getting
rid of the ones in pat_disable() and the pat disabled case in pat_init().
I've reworked the whole thing into the patch below.
Thanks,
tglx
8<---------------------
Subject: x86/mm/pat: Don't report PAT on CPUs that don't support it
From: Mikulas Patocka <mpatocka@redhat.com>
Date: Tue, 6 Jun 2017 18:49:39 -0400 (EDT)
The pat_enabled() logic is broken on CPUs which do not support PAT and
where the initialization code fails to call pat_init(). Due to that the
enabled flag stays true and pat_enabled() returns true wrongfully.
As a consequence the mappings, e.g. for Xorg, are set up with the wrong
caching mode and the required MTRR setups are omitted.
To cure this the following changes are required:
1) Make pat_enabled() return true only if PAT initialization was
invoked and successful.
2) Invoke init_cache_modes() unconditionally in setup_arch() and
remove the extra callsites in pat_disable() and the pat disabled
code path in pat_init().
Also rename __pat_enabled to pat_disabled to reflect the real purpose of
this variable.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: Bernhard Held <berny156@gmx.de>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: "Luis R. Rodriguez" <mcgrof@suse.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
---
arch/x86/include/asm/pat.h | 1 +
arch/x86/kernel/setup.c | 7 +++++++
arch/x86/mm/pat.c | 22 +++++++++-------------
3 files changed, 17 insertions(+), 13 deletions(-)
--- a/arch/x86/include/asm/pat.h
+++ b/arch/x86/include/asm/pat.h
@@ -7,6 +7,7 @@
bool pat_enabled(void);
void pat_disable(const char *reason);
extern void pat_init(void);
+extern void init_cache_modes(void);
extern int reserve_memtype(u64 start, u64 end,
enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1076,6 +1076,13 @@ void __init setup_arch(char **cmdline_p)
max_possible_pfn = max_pfn;
/*
+ * This call is required when the CPU does not support PAT. If
+ * mtrr_bp_init() invoked it already via pat_init() the call has no
+ * effect.
+ */
+ init_cache_modes();
+
+ /*
* Define random base addresses for memory sections after max_pfn is
* defined and before each memory section base is used.
*/
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -37,14 +37,13 @@
#undef pr_fmt
#define pr_fmt(fmt) "" fmt
-static bool boot_cpu_done;
-
-static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
-static void init_cache_modes(void);
+static bool __read_mostly boot_cpu_done;
+static bool __read_mostly pat_disabled = !IS_ENABLED(CONFIG_X86_PAT);
+static bool __read_mostly pat_initialized;
void pat_disable(const char *reason)
{
- if (!__pat_enabled)
+ if (pat_disabled)
return;
if (boot_cpu_done) {
@@ -52,10 +51,8 @@ void pat_disable(const char *reason)
return;
}
- __pat_enabled = 0;
+ pat_disabled = true;
pr_info("x86/PAT: %s\n", reason);
-
- init_cache_modes();
}
static int __init nopat(char *str)
@@ -67,7 +64,7 @@ early_param("nopat", nopat);
bool pat_enabled(void)
{
- return !!__pat_enabled;
+ return pat_initialized;
}
EXPORT_SYMBOL_GPL(pat_enabled);
@@ -225,6 +222,7 @@ static void pat_bsp_init(u64 pat)
}
wrmsrl(MSR_IA32_CR_PAT, pat);
+ __pat_initialized = true;
__init_cache_modes(pat);
}
@@ -242,7 +240,7 @@ static void pat_ap_init(u64 pat)
wrmsrl(MSR_IA32_CR_PAT, pat);
}
-static void init_cache_modes(void)
+void init_cache_modes(void)
{
u64 pat = 0;
static int init_cm_done;
@@ -306,10 +304,8 @@ void pat_init(void)
u64 pat;
struct cpuinfo_x86 *c = &boot_cpu_data;
- if (!pat_enabled()) {
- init_cache_modes();
+ if (pat_disabled)
return;
- }
if ((c->x86_vendor == X86_VENDOR_INTEL) &&
(((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
[toc] | [prev] | [next] | [standalone]
| From | Mikulas Patocka <mpatocka@redhat.com> |
|---|---|
| Date | 2017-07-05 01:10 +0200 |
| Subject | [PATCH v3] X86: don't report PAT on CPUs that don't support it |
| Message-ID | <tZF7c-6uZ-5@gated-at.bofh.it> |
| In reply to | #1680985 |
On Tue, 4 Jul 2017, Thomas Gleixner wrote:
> On Mon, 3 Jul 2017, Mikulas Patocka wrote:
> > Is there any progress with this patch? Will you accept it or do you want
> > some changes to it?
>
> Aside of the unparseable changelog, that patch is mostly duct tape.
>
> 1) __pat_enabled should be renamed to pat_disabled, as that is the actual
> purpose of that variable
>
> 2) Making the call to init_cache_modes() conditional in setup_arch() is
> pointless. init_cache_modes() has it's own protection against multiple
> invocations.
>
> 3) It adds yet another invocation of init_cache_modes() instead of getting
> rid of the ones in pat_disable() and the pat disabled case in pat_init().
>
> I've reworked the whole thing into the patch below.
>
> Thanks,
>
> tglx
Yes - renaming __pat_enabled to pat_disabled is a good thing.
Just one more change - init_cache_modes() is protected against multiple
calls, but pat_bsp_init() calls __init_cache_modes() (not
init_cacha_modes()). The generic code would call init_cache_modes() later
and init_cache_modes() would do the initialization again - it would be
mostly harmless because it would just read the pat MSR that pat_bsp_init
have written and call __init_cache_modes() with the same value - the
symptom is that on machines with PAT we see this line twice in the syslog:
[ 0.000000] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WC UC- WT
[ 0.000000] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WC UC- WT
I fixed this double initialization by moving the variable init_cm_done to
file scope and setting it in __init_cache_modes().
Mikulas
8<---------------------
Subject: x86/mm/pat: Don't report PAT on CPUs that don't support it
From: Mikulas Patocka <mpatocka@redhat.com>
Date: Tue, 6 Jun 2017 18:49:39 -0400 (EDT)
The pat_enabled() logic is broken on CPUs which do not support PAT and
where the initialization code fails to call pat_init(). Due to that the
enabled flag stays true and pat_enabled() returns true wrongfully.
As a consequence the mappings, e.g. for Xorg, are set up with the wrong
caching mode and the required MTRR setups are omitted.
To cure this the following changes are required:
1) Make pat_enabled() return true only if PAT initialization was
invoked and successful.
2) Invoke init_cache_modes() unconditionally in setup_arch() and
remove the extra callsites in pat_disable() and the pat disabled
code path in pat_init().
Also rename __pat_enabled to pat_disabled to reflect the real purpose of
this variable.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: Bernhard Held <berny156@gmx.de>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: "Luis R. Rodriguez" <mcgrof@suse.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: stable@vger.kernel.org # v4.2+
---
arch/x86/include/asm/pat.h | 1 +
arch/x86/kernel/setup.c | 7 +++++++
arch/x86/mm/pat.c | 28 ++++++++++++----------------
3 files changed, 20 insertions(+), 16 deletions(-)
Index: linux-2.6/arch/x86/include/asm/pat.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/pat.h
+++ linux-2.6/arch/x86/include/asm/pat.h
@@ -7,6 +7,7 @@
bool pat_enabled(void);
void pat_disable(const char *reason);
extern void pat_init(void);
+extern void init_cache_modes(void);
extern int reserve_memtype(u64 start, u64 end,
enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -1076,6 +1076,13 @@ void __init setup_arch(char **cmdline_p)
max_possible_pfn = max_pfn;
/*
+ * This call is required when the CPU does not support PAT. If
+ * mtrr_bp_init() invoked it already via pat_init() the call has no
+ * effect.
+ */
+ init_cache_modes();
+
+ /*
* Define random base addresses for memory sections after max_pfn is
* defined and before each memory section base is used.
*/
Index: linux-2.6/arch/x86/mm/pat.c
===================================================================
--- linux-2.6.orig/arch/x86/mm/pat.c
+++ linux-2.6/arch/x86/mm/pat.c
@@ -37,14 +37,14 @@
#undef pr_fmt
#define pr_fmt(fmt) "" fmt
-static bool boot_cpu_done;
-
-static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
-static void init_cache_modes(void);
+static bool __read_mostly boot_cpu_done;
+static bool __read_mostly pat_disabled = !IS_ENABLED(CONFIG_X86_PAT);
+static bool __read_mostly pat_initialized;
+static bool __read_mostly init_cm_done;
void pat_disable(const char *reason)
{
- if (!__pat_enabled)
+ if (pat_disabled)
return;
if (boot_cpu_done) {
@@ -52,10 +52,8 @@ void pat_disable(const char *reason)
return;
}
- __pat_enabled = 0;
+ pat_disabled = true;
pr_info("x86/PAT: %s\n", reason);
-
- init_cache_modes();
}
static int __init nopat(char *str)
@@ -67,7 +65,7 @@ early_param("nopat", nopat);
bool pat_enabled(void)
{
- return !!__pat_enabled;
+ return pat_initialized;
}
EXPORT_SYMBOL_GPL(pat_enabled);
@@ -205,6 +203,8 @@ static void __init_cache_modes(u64 pat)
update_cache_mode_entry(i, cache);
}
pr_info("x86/PAT: Configuration [0-7]: %s\n", pat_msg);
+
+ init_cm_done = true;
}
#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
@@ -225,6 +225,7 @@ static void pat_bsp_init(u64 pat)
}
wrmsrl(MSR_IA32_CR_PAT, pat);
+ pat_initialized = true;
__init_cache_modes(pat);
}
@@ -242,10 +243,9 @@ static void pat_ap_init(u64 pat)
wrmsrl(MSR_IA32_CR_PAT, pat);
}
-static void init_cache_modes(void)
+void init_cache_modes(void)
{
u64 pat = 0;
- static int init_cm_done;
if (init_cm_done)
return;
@@ -287,8 +287,6 @@ static void init_cache_modes(void)
}
__init_cache_modes(pat);
-
- init_cm_done = 1;
}
/**
@@ -306,10 +304,8 @@ void pat_init(void)
u64 pat;
struct cpuinfo_x86 *c = &boot_cpu_data;
- if (!pat_enabled()) {
- init_cache_modes();
+ if (pat_disabled)
return;
- }
if ((c->x86_vendor == X86_VENDOR_INTEL) &&
(((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Mikulas Patocka <tipbot@zytor.com> |
|---|---|
| Date | 2017-07-05 09:20 +0200 |
| Subject | [tip:x86/urgent] x86/mm/pat: Don't report PAT on CPUs that don't support it |
| Message-ID | <tZMLo-3av-31@gated-at.bofh.it> |
| In reply to | #1681209 |
Commit-ID: 99c13b8c8896d7bcb92753bf0c63a8de4326e78d
Gitweb: http://git.kernel.org/tip/99c13b8c8896d7bcb92753bf0c63a8de4326e78d
Author: Mikulas Patocka <mpatocka@redhat.com>
AuthorDate: Tue, 4 Jul 2017 19:04:23 -0400
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 5 Jul 2017 09:01:24 +0200
x86/mm/pat: Don't report PAT on CPUs that don't support it
The pat_enabled() logic is broken on CPUs which do not support PAT and
where the initialization code fails to call pat_init(). Due to that the
enabled flag stays true and pat_enabled() returns true wrongfully.
As a consequence the mappings, e.g. for Xorg, are set up with the wrong
caching mode and the required MTRR setups are omitted.
To cure this the following changes are required:
1) Make pat_enabled() return true only if PAT initialization was
invoked and successful.
2) Invoke init_cache_modes() unconditionally in setup_arch() and
remove the extra callsites in pat_disable() and the pat disabled
code path in pat_init().
Also rename __pat_enabled to pat_disabled to reflect the real purpose of
this variable.
Fixes: 9cd25aac1f44 ("x86/mm/pat: Emulate PAT when it is disabled")
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Bernhard Held <berny156@gmx.de>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: "Luis R. Rodriguez" <mcgrof@suse.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: stable@vger.kernel.org
Link: http://lkml.kernel.org/r/alpine.LRH.2.02.1707041749300.3456@file01.intranet.prod.int.rdu2.redhat.com
---
arch/x86/include/asm/pat.h | 1 +
arch/x86/kernel/setup.c | 7 +++++++
arch/x86/mm/pat.c | 28 ++++++++++++----------------
3 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
index 0b1ff4c..fffb279 100644
--- a/arch/x86/include/asm/pat.h
+++ b/arch/x86/include/asm/pat.h
@@ -7,6 +7,7 @@
bool pat_enabled(void);
void pat_disable(const char *reason);
extern void pat_init(void);
+extern void init_cache_modes(void);
extern int reserve_memtype(u64 start, u64 end,
enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 65622f0..3486d04 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1076,6 +1076,13 @@ void __init setup_arch(char **cmdline_p)
max_possible_pfn = max_pfn;
/*
+ * This call is required when the CPU does not support PAT. If
+ * mtrr_bp_init() invoked it already via pat_init() the call has no
+ * effect.
+ */
+ init_cache_modes();
+
+ /*
* Define random base addresses for memory sections after max_pfn is
* defined and before each memory section base is used.
*/
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 9b78685..4597950 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -37,14 +37,14 @@
#undef pr_fmt
#define pr_fmt(fmt) "" fmt
-static bool boot_cpu_done;
-
-static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
-static void init_cache_modes(void);
+static bool __read_mostly boot_cpu_done;
+static bool __read_mostly pat_disabled = !IS_ENABLED(CONFIG_X86_PAT);
+static bool __read_mostly pat_initialized;
+static bool __read_mostly init_cm_done;
void pat_disable(const char *reason)
{
- if (!__pat_enabled)
+ if (pat_disabled)
return;
if (boot_cpu_done) {
@@ -52,10 +52,8 @@ void pat_disable(const char *reason)
return;
}
- __pat_enabled = 0;
+ pat_disabled = true;
pr_info("x86/PAT: %s\n", reason);
-
- init_cache_modes();
}
static int __init nopat(char *str)
@@ -67,7 +65,7 @@ early_param("nopat", nopat);
bool pat_enabled(void)
{
- return !!__pat_enabled;
+ return pat_initialized;
}
EXPORT_SYMBOL_GPL(pat_enabled);
@@ -205,6 +203,8 @@ static void __init_cache_modes(u64 pat)
update_cache_mode_entry(i, cache);
}
pr_info("x86/PAT: Configuration [0-7]: %s\n", pat_msg);
+
+ init_cm_done = true;
}
#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
@@ -225,6 +225,7 @@ static void pat_bsp_init(u64 pat)
}
wrmsrl(MSR_IA32_CR_PAT, pat);
+ pat_initialized = true;
__init_cache_modes(pat);
}
@@ -242,10 +243,9 @@ static void pat_ap_init(u64 pat)
wrmsrl(MSR_IA32_CR_PAT, pat);
}
-static void init_cache_modes(void)
+void init_cache_modes(void)
{
u64 pat = 0;
- static int init_cm_done;
if (init_cm_done)
return;
@@ -287,8 +287,6 @@ static void init_cache_modes(void)
}
__init_cache_modes(pat);
-
- init_cm_done = 1;
}
/**
@@ -306,10 +304,8 @@ void pat_init(void)
u64 pat;
struct cpuinfo_x86 *c = &boot_cpu_data;
- if (!pat_enabled()) {
- init_cache_modes();
+ if (pat_disabled)
return;
- }
if ((c->x86_vendor == X86_VENDOR_INTEL) &&
(((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web