]> xenbits.xensource.com Git - people/jgross/linux.git/commitdiff
x86/mtrr: replace vendor tests in MTRR code
authorJuergen Gross <jgross@suse.com>
Fri, 17 Feb 2023 14:22:16 +0000 (15:22 +0100)
committerJuergen Gross <jgross@suse.com>
Tue, 2 May 2023 12:08:42 +0000 (14:08 +0200)
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.

Signed-off-by: Juergen Gross <jgross@suse.com>
Tested-by: Michael Kelley <mikelley@microsoft.com>
---
V3:
- new patch
V4:
- use cpu_feature_enabled(X86_FEATURE_MTRR) for testing generic MTRRs
  (Boris Petkov)
V6:
- eliminate set_num_var_ranges() (Boris Petkov)

arch/x86/kernel/cpu/mtrr/amd.c
arch/x86/kernel/cpu/mtrr/centaur.c
arch/x86/kernel/cpu/mtrr/cleanup.c
arch/x86/kernel/cpu/mtrr/cyrix.c
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/cpu/mtrr/mtrr.c
arch/x86/kernel/cpu/mtrr/mtrr.h

index eff6ac62c0ff41586a7d36e30b09dfdf6d56ead1..ef3e8e42b7820ea5c7746f25b4bcec70f57e5f9d 100644 (file)
@@ -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,
index b8a74eddde83b0eda80f0ce090f75422dcb88f02..4466ddeb0125844bd26761f37b43e32fb2f81760 100644 (file)
@@ -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,
index ca2d567e729e22b04fc23268019d973b3311f71a..4a979086f00e24da5a991698d1904824cb6b5cd5 100644 (file)
@@ -689,7 +689,7 @@ int __init mtrr_cleanup(void)
        int index_good;
        int i;
 
-       if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1)
+       if (!cpu_feature_enabled(X86_FEATURE_MTRR) || enable_mtrr_cleanup < 1)
                return 0;
 
        rdmsr(MSR_MTRRdefType, def, dummy);
@@ -886,7 +886,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
         * 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);
index 173b9e01e6231da0831cfed0580fcbf2957e57b8..238dad57d4d6bc9f34184bbc16f950dd87a8f03e 100644 (file)
@@ -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,
index 7433b2d2e4ec627c36e264c751cdc54f669b35bb..78226660d1211a41d908eda6c0246e9a19e2e9d1 100644 (file)
@@ -853,7 +853,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)) {
index 9173ed396508d44f78db52099217395149f78fc6..3351730447e1aadad39d617a96aa17e6fcdf3c19 100644 (file)
@@ -103,21 +103,6 @@ static int have_wrcomb(void)
        return mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0;
 }
 
-/*  This function returns the number of variable MTRRs  */
-static void __init set_num_var_ranges(bool use_generic)
-{
-       unsigned long config = 0, dummy;
-
-       if (use_generic)
-               rdmsr(MSR_MTRRcap, config, dummy);
-       else if (is_cpu(AMD) || is_cpu(HYGON))
-               config = 2;
-       else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
-               config = 8;
-
-       num_var_ranges = config & MTRR_CAP_VCNT;
-}
-
 static void __init init_table(void)
 {
        int i, max;
@@ -627,6 +612,7 @@ void __init mtrr_bp_init(void)
 {
        bool generic_mtrrs = cpu_feature_enabled(X86_FEATURE_MTRR);
        const char *why = "(not available)";
+       unsigned long config, dummy;
 
        mtrr_set_mask();
 
@@ -664,7 +650,13 @@ void __init mtrr_bp_init(void)
        }
 
        if (mtrr_enabled()) {
-               set_num_var_ranges(mtrr_if == &generic_mtrr_ops);
+               /* Get the number of variable MTRR ranges. */
+               if (mtrr_if == &generic_mtrr_ops)
+                       rdmsr(MSR_MTRRcap, config, dummy);
+               else
+                       config = mtrr_if->var_regs;
+               num_var_ranges = config & MTRR_CAP_VCNT;
+
                init_table();
                if (mtrr_if == &generic_mtrr_ops) {
                        /* BIOS may override */
index a00987e6cc1c11368367bce96bda8b50ef878882..0dd11e41baa6d2ce031dde4512dbdaa637cb1983 100644 (file)
@@ -13,7 +13,7 @@
 extern unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
 
 struct mtrr_ops {
-       u32     vendor;
+       u32     var_regs;
        void    (*set)(unsigned int reg, unsigned long base,
                       unsigned long size, mtrr_type type);
        void    (*get)(unsigned int reg, unsigned long *base,
@@ -53,8 +53,6 @@ bool get_mtrr_state(void);
 
 extern const struct mtrr_ops *mtrr_if;
 
-#define is_cpu(vnd)    (mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd)
-
 extern unsigned int num_var_ranges;
 extern u64 mtrr_tom2;
 extern struct mtrr_state_type mtrr_state;