Commit 03409069 authored by Juergen Gross's avatar Juergen Gross Committed by Borislav Petkov (AMD)
Browse files

x86/mtrr: Replace vendor tests in MTRR code



Modern CPUs all share the same MTRR interface implemented via
generic_mtrr_ops.

At several places in MTRR code this generic interface is deduced via
is_cpu(INTEL) tests, which is only working due to X86_VENDOR_INTEL
being 0 (the is_cpu() macro is testing mtrr_if->vendor, which isn't
explicitly set in generic_mtrr_ops).

Test the generic CPU feature X86_FEATURE_MTRR instead.

The only other place where the .vendor member of struct mtrr_ops is
being used is in set_num_var_ranges(), where depending on the vendor
the number of MTRR registers is determined. This can easily be changed
by replacing .vendor with the static number of MTRR registers.

It should be noted that the test "is_cpu(HYGON)" wasn't ever returning
true, as there is no struct mtrr_ops with that vendor information.

[ bp: Use mtrr_enabled() before doing mtrr_if-> accesses, esp. in
  mtrr_trim_uncached_memory() which gets called independently from
  whether mtrr_if is set or not. ]

Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230502120931.20719-7-jgross@suse.com


Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
parent a153f254
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ amd_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
}

const struct mtrr_ops amd_mtrr_ops = {
	.vendor            = X86_VENDOR_AMD,
	.var_regs          = 2,
	.set               = amd_set_mtrr,
	.get               = amd_get_mtrr,
	.get_free_region   = generic_get_free_region,
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ centaur_validate_add_page(unsigned long base, unsigned long size, unsigned int t
}

const struct mtrr_ops centaur_mtrr_ops = {
	.vendor            = X86_VENDOR_CENTAUR,
	.var_regs          = 8,
	.set               = centaur_set_mcr,
	.get               = centaur_get_mcr,
	.get_free_region   = centaur_get_free_region,
+8 −2
Original line number Diff line number Diff line
@@ -689,7 +689,10 @@ int __init mtrr_cleanup(void)
	int index_good;
	int i;

	if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1)
	if (!mtrr_enabled())
		return 0;

	if (!cpu_feature_enabled(X86_FEATURE_MTRR) || enable_mtrr_cleanup < 1)
		return 0;

	rdmsr(MSR_MTRRdefType, def, dummy);
@@ -882,11 +885,14 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
	/* extra one for all 0 */
	int num[MTRR_NUM_TYPES + 1];

	if (!mtrr_enabled())
		return 0;

	/*
	 * Make sure we only trim uncachable memory on machines that
	 * support the Intel MTRR architecture:
	 */
	if (!is_cpu(INTEL) || disable_mtrr_trim)
	if (!cpu_feature_enabled(X86_FEATURE_MTRR) || disable_mtrr_trim)
		return 0;

	rdmsr(MSR_MTRRdefType, def, dummy);
+1 −1
Original line number Diff line number Diff line
@@ -235,7 +235,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base,
}

const struct mtrr_ops cyrix_mtrr_ops = {
	.vendor            = X86_VENDOR_CYRIX,
	.var_regs          = 8,
	.set               = cyrix_set_arr,
	.get               = cyrix_get_arr,
	.get_free_region   = cyrix_get_free_region,
+1 −1
Original line number Diff line number Diff line
@@ -843,7 +843,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size,
	 * For Intel PPro stepping <= 7
	 * must be 4 MiB aligned and not touch 0x70000000 -> 0x7003FFFF
	 */
	if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 &&
	if (mtrr_if == &generic_mtrr_ops && boot_cpu_data.x86 == 6 &&
	    boot_cpu_data.x86_model == 1 &&
	    boot_cpu_data.x86_stepping <= 7) {
		if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
Loading