Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9dac6290 authored by Borislav Petkov's avatar Borislav Petkov Committed by Ingo Molnar
Browse files

x86/mm/pat: Untangle pat_init()



Split it into a BSP and AP version which makes the PAT
initialization path actually readable again.

Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarToshi Kani <toshi.kani@hp.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Elliott@hp.com
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Luis R. Rodriguez <mcgrof@suse.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: arnd@arndb.de
Cc: hch@lst.de
Cc: hmh@hmh.eng.br
Cc: jgross@suse.com
Cc: konrad.wilk@oracle.com
Cc: linux-mm <linux-mm@kvack.org>
Cc: linux-nvdimm@lists.01.org
Cc: stefan.bader@canonical.com
Cc: yigal@plexistor.com
Link: http://lkml.kernel.org/r/1433436928-31903-2-git-send-email-bp@alien8.de


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent d6472302
Loading
Loading
Loading
Loading
+40 −29
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#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 inline void pat_disable(const char *reason)
@@ -194,31 +196,47 @@ void pat_init_cache_modes(void)

#define PAT(x, y)	((u64)PAT_ ## y << ((x)*8))

void pat_init(void)
static void pat_bsp_init(u64 pat)
{
	u64 pat;
	bool boot_cpu = !boot_pat_state;

	if (!pat_enabled())
	if (!cpu_has_pat) {
		pat_disable("PAT not supported by CPU.");
		return;
	}

	if (!cpu_has_pat) {
	rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
	if (!boot_pat_state) {
			pat_disable("PAT not supported by CPU.");
		pat_disable("PAT MSR is 0, disabled.");
		return;
		} else {
	}

	wrmsrl(MSR_IA32_CR_PAT, pat);

	pat_init_cache_modes();
}

static void pat_ap_init(u64 pat)
{
	if (!cpu_has_pat) {
		/*
			 * If this happens we are on a secondary CPU, but
			 * switched to PAT on the boot CPU. We have no way to
			 * undo PAT.
		 * If this happens we are on a secondary CPU, but switched to
		 * PAT on the boot CPU. We have no way to undo PAT.
		 */
			pr_err("x86/PAT: PAT enabled, but not supported by secondary CPU\n");
			BUG();
		panic("x86/PAT: PAT enabled, but not supported by secondary CPU\n");
	}

	wrmsrl(MSR_IA32_CR_PAT, pat);
}

	/* Set PWT to Write-Combining. All other bits stay the same */
void pat_init(void)
{
	u64 pat;

	if (!pat_enabled())
		return;

	/*
	 * Set PWT to Write-Combining. All other bits stay the same:
	 *
	 * PTE encoding used in Linux:
	 *      PAT
	 *      |PCD
@@ -233,19 +251,12 @@ void pat_init(void)
	pat = PAT(0, WB) | PAT(1, WC) | PAT(2, UC_MINUS) | PAT(3, UC) |
	      PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC);

	/* Boot CPU check */
	if (!boot_pat_state) {
		rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
		if (!boot_pat_state) {
			pat_disable("PAT read returns always zero, disabled.");
			return;
		}
	if (!boot_cpu_done) {
		pat_bsp_init(pat);
		boot_cpu_done = true;
	} else {
		pat_ap_init(pat);
	}

	wrmsrl(MSR_IA32_CR_PAT, pat);

	if (boot_cpu)
		pat_init_cache_modes();
}

#undef PAT