Do a global flush tlb after splitting the large page and before we do the
actual change page attribute in the PTE.
With out this, we violate the TLB application note, which says
"The TLBs may contain both ordinary and large-page translations for
a 4-KByte range of linear addresses. This may occur if software
modifies the paging structures so that the page size used for the
address range changes. If the two translations differ with respect
to page frame or attributes (e.g., permissions), processor behavior
is undefined and may be implementation-specific."
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
Index: tip/arch/x86/mm/pageattr.c
===================================================================
--- tip.orig/arch/x86/mm/pageattr.c 2008-09-11 13:25:55.000000000 -0700
+++ tip/arch/x86/mm/pageattr.c 2008-09-11 13:25:57.000000000 -0700
@@ -131,6 +131,18 @@
mb();
}
+static void __global_flush_tlb(void *arg)
+{
+ __flush_tlb_all();
+}
+
+static void global_flush_tlb(void)
+{
+ BUG_ON(irqs_disabled());
+
+ on_each_cpu(__global_flush_tlb, NULL, 1);
+}
+
static void __cpa_flush_all(void *arg)
{
unsigned long cache = (unsigned long)arg;
@@ -506,6 +518,25 @@
ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte)));
pgprot_val(ref_prot) |= _PAGE_PRESENT;
__set_pmd_pte(kpte, address, mk_pte(base, ref_prot));
+
+ /*
+ * Do a global flush tlb after splitting the large page
+ * and before we do the actual change page attribute in the PTE.
+ *
+ * With out this, we violate the TLB application note, which says
+ * "The TLBs may contain both ordinary and large-page translations for
+ * a 4-KByte range of linear addresses. This may occur if software
+ * modifies the paging structures so that the page size used for the
+ * address range changes. If the two translations differ with respect
+ * to page frame or attributes (e.g., permissions), processor behavior
+ * is undefined and may be ...