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

Commit 75a04811 authored by H. Peter Anvin's avatar H. Peter Anvin
Browse files

x86: handle PAT more like other CPU features



Impact: Cleanup

When PAT was originally introduced, it was handled specially for a few
reasons:

- PAT bugs are hard to track down, so we wanted to maintain a
  whitelist of CPUs.
- The i386 and x86-64 CPUID code was not yet unified.

Both of these are now obsolete, so handle PAT like any other features,
including ordinary feature blacklisting due to known bugs.

Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent b1882e68
Loading
Loading
Loading
Loading
+0 −4
Original line number Original line Diff line number Diff line
@@ -5,10 +5,8 @@


#ifdef CONFIG_X86_PAT
#ifdef CONFIG_X86_PAT
extern int pat_enabled;
extern int pat_enabled;
extern void validate_pat_support(struct cpuinfo_x86 *c);
#else
#else
static const int pat_enabled;
static const int pat_enabled;
static inline void validate_pat_support(struct cpuinfo_x86 *c) { }
#endif
#endif


extern void pat_init(void);
extern void pat_init(void);
@@ -17,6 +15,4 @@ extern int reserve_memtype(u64 start, u64 end,
		unsigned long req_type, unsigned long *ret_type);
		unsigned long req_type, unsigned long *ret_type);
extern int free_memtype(u64 start, u64 end);
extern int free_memtype(u64 start, u64 end);


extern void pat_disable(char *reason);

#endif /* _ASM_X86_PAT_H */
#endif /* _ASM_X86_PAT_H */
+0 −34
Original line number Original line Diff line number Diff line
@@ -143,37 +143,3 @@ void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c)
	return;
	return;
#endif
#endif
}
}

#ifdef CONFIG_X86_PAT
void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
{
	if (!cpu_has_pat)
		pat_disable("PAT not supported by CPU.");

	switch (c->x86_vendor) {
	case X86_VENDOR_INTEL:
		/*
		 * There is a known erratum on Pentium III and Core Solo
		 * and Core Duo CPUs.
		 * " Page with PAT set to WC while associated MTRR is UC
		 *   may consolidate to UC "
		 * Because of this erratum, it is better to stick with
		 * setting WC in MTRR rather than using PAT on these CPUs.
		 *
		 * Enable PAT WC only on P4, Core 2 or later CPUs.
		 */
		if (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 15))
			return;

		pat_disable("PAT WC disabled due to known CPU erratum.");
		return;

	case X86_VENDOR_AMD:
	case X86_VENDOR_CENTAUR:
	case X86_VENDOR_TRANSMETA:
		return;
	}

	pat_disable("PAT disabled. Not yet verified on this CPU type.");
}
#endif
+0 −2
Original line number Original line Diff line number Diff line
@@ -570,8 +570,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
	if (this_cpu->c_early_init)
	if (this_cpu->c_early_init)
		this_cpu->c_early_init(c);
		this_cpu->c_early_init(c);


	validate_pat_support(c);

#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
	c->cpu_index = boot_cpu_id;
	c->cpu_index = boot_cpu_id;
#endif
#endif
+12 −0
Original line number Original line Diff line number Diff line
@@ -50,6 +50,18 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
	}
	}


	/*
	 * There is a known erratum on Pentium III and Core Solo
	 * and Core Duo CPUs.
	 * " Page with PAT set to WC while associated MTRR is UC
	 *   may consolidate to UC "
	 * Because of this erratum, it is better to stick with
	 * setting WC in MTRR rather than using PAT on these CPUs.
	 *
	 * Enable PAT WC only on P4, Core 2 or later CPUs.
	 */
	if (c->x86 == 6 && c->x86_model < 15)
		clear_cpu_cap(c, X86_FEATURE_PAT);
}
}


#ifdef CONFIG_X86_32
#ifdef CONFIG_X86_32
+20 −11
Original line number Original line Diff line number Diff line
@@ -30,7 +30,7 @@
#ifdef CONFIG_X86_PAT
#ifdef CONFIG_X86_PAT
int __read_mostly pat_enabled = 1;
int __read_mostly pat_enabled = 1;


void __cpuinit pat_disable(char *reason)
void __cpuinit pat_disable(const char *reason)
{
{
	pat_enabled = 0;
	pat_enabled = 0;
	printk(KERN_INFO "%s\n", reason);
	printk(KERN_INFO "%s\n", reason);
@@ -42,6 +42,11 @@ static int __init nopat(char *str)
	return 0;
	return 0;
}
}
early_param("nopat", nopat);
early_param("nopat", nopat);
#else
static inline void pat_disable(const char *reason)
{
	(void)reason;
}
#endif
#endif




@@ -78,8 +83,11 @@ void pat_init(void)
	if (!pat_enabled)
	if (!pat_enabled)
		return;
		return;


	/* Paranoia check. */
	if (!cpu_has_pat) {
	if (!cpu_has_pat && boot_pat_state) {
		if (!boot_pat_state) {
			pat_disable("PAT not supported by CPU.");
			return;
		} else {
			/*
			/*
			 * If this happens we are on a secondary CPU, but
			 * If this happens we are on a secondary CPU, but
			 * switched to PAT on the boot CPU. We have no way to
			 * switched to PAT on the boot CPU. We have no way to
@@ -89,6 +97,7 @@ void pat_init(void)
			       "but not supported by secondary CPU\n");
			       "but not supported by secondary CPU\n");
			BUG();
			BUG();
		}
		}
	}


	/* Set PWT to Write-Combining. All other bits stay the same */
	/* Set PWT to Write-Combining. All other bits stay the same */
	/*
	/*