patch-2.4.22 linux-2.4.22/arch/x86_64/mm/init.c
Next file: linux-2.4.22/arch/x86_64/mm/k8topology.c
Previous file: linux-2.4.22/arch/x86_64/mm/fault.c
Back to the patch index
Back to the overall index
- Lines: 58
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/arch/x86_64/mm/init.c
- Orig date:
2003-06-13 07:51:32.000000000 -0700
diff -urN linux-2.4.21/arch/x86_64/mm/init.c linux-2.4.22/arch/x86_64/mm/init.c
@@ -418,35 +418,31 @@
#endif
}
-void __init __map_kernel_range(void *address, int len, pgprot_t prot)
+/* Unmap a kernel mapping if it exists. This is useful to avoid prefetches
+ from the CPU leading to inconsistent cache lines. address and size
+ must be aligned to 2MB boundaries.
+ Does nothing when the mapping doesn't exist. */
+void __init clear_kernel_mapping(unsigned long address, unsigned long size)
{
- int i;
- void *end = address + len;
- BUG_ON((pgprot_val(prot) & _PAGE_PSE) == 0);
- address = (void *)((unsigned long)address & LARGE_PAGE_MASK);
+ unsigned long end = address + size;
+
+ BUG_ON(address & ~LARGE_PAGE_MASK);
+ BUG_ON(size & ~LARGE_PAGE_MASK);
+
for (; address < end; address += LARGE_PAGE_SIZE) {
- pml4_t *pml4;
- pgd_t *pgd;
- pmd_t *pmd;
-
- pml4 = pml4_offset_k((unsigned long) address);
- if (pml4_none(*pml4)) {
- void *p = (void *)get_zeroed_page(GFP_KERNEL);
- if (!p) panic("Cannot map kernel range");
- for (i = 0; i < smp_num_cpus; i++) {
- set_pml4((pml4_t *)(cpu_pda[i].level4_pgt) +
- pml4_index((unsigned long)address),
- mk_kernel_pml4(virt_to_phys(p),KERNPG_TABLE));
- }
- }
- pgd = pgd_offset_k((unsigned long)address);
- if (pgd_none(*pgd)) {
- void *p = (void *)get_zeroed_page(GFP_KERNEL);
- if (!p) panic("Cannot map kernel range");
- set_pgd(pgd, __mk_pgd(virt_to_phys(p), KERNPG_TABLE));
+ pgd_t *pgd = pgd_offset_k(address);
+ if (!pgd || pgd_none(*pgd))
+ continue;
+ pmd_t *pmd = pmd_offset(pgd, address);
+ if (!pmd || pmd_none(*pmd))
+ continue;
+ if (0 == (pmd_val(*pmd) & _PAGE_PSE)) {
+ /* Could handle this, but it should not happen currently. */
+ printk(KERN_ERR
+ "clear_kernel_mapping: mapping has been split. will leak memory\n");
+ pmd_ERROR(*pmd);
}
- pmd = pmd_offset(pgd, (unsigned long) address);
- set_pmd(pmd, __mk_pmd(virt_to_phys(address), prot));
+ set_pmd(pmd, __pmd(0));
}
__flush_tlb_all();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)