forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/arch/x86/kernel/cpu/mtrr/generic.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * This only handles 32bit MTRR on 32bit hosts. This is strictly wrong
34 * because MTRRs can span up to 40 bits (36bits on most modern x86)
....@@ -14,7 +15,7 @@
1415 #include <asm/tlbflush.h>
1516 #include <asm/mtrr.h>
1617 #include <asm/msr.h>
17
-#include <asm/pat.h>
18
+#include <asm/memtype.h>
1819
1920 #include "mtrr.h"
2021
....@@ -742,7 +743,15 @@
742743 /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
743744 cr0 = read_cr0() | X86_CR0_CD;
744745 write_cr0(cr0);
745
- wbinvd();
746
+
747
+ /*
748
+ * Cache flushing is the most time-consuming step when programming
749
+ * the MTRRs. Fortunately, as per the Intel Software Development
750
+ * Manual, we can skip it if the processor supports cache self-
751
+ * snooping.
752
+ */
753
+ if (!static_cpu_has(X86_FEATURE_SELFSNOOP))
754
+ wbinvd();
746755
747756 /* Save value of CR4 and clear Page Global Enable (bit 7) */
748757 if (boot_cpu_has(X86_FEATURE_PGE)) {
....@@ -752,21 +761,24 @@
752761
753762 /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
754763 count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
755
- __flush_tlb();
764
+ flush_tlb_local();
756765
757766 /* Save MTRR state */
758767 rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
759768
760769 /* Disable MTRRs, and set the default type to uncached */
761770 mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
762
- wbinvd();
771
+
772
+ /* Again, only flush caches if we have to. */
773
+ if (!static_cpu_has(X86_FEATURE_SELFSNOOP))
774
+ wbinvd();
763775 }
764776
765777 static void post_set(void) __releases(set_atomicity_lock)
766778 {
767779 /* Flush TLBs (no need to flush caches - they are disabled) */
768780 count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
769
- __flush_tlb();
781
+ flush_tlb_local();
770782
771783 /* Intel (P6) standard MTRRs */
772784 mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
....@@ -798,7 +810,7 @@
798810 local_irq_restore(flags);
799811
800812 /* Use the atomic bitops to update the global mask */
801
- for (count = 0; count < sizeof mask * 8; ++count) {
813
+ for (count = 0; count < sizeof(mask) * 8; ++count) {
802814 if (mask & 0x01)
803815 set_bit(count, &smp_changes_mask);
804816 mask >>= 1;