]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/mm/init_64.c
x86: mark the .rodata section also NX
[linux-2.6-omap-h63xx.git] / arch / x86 / mm / init_64.c
index cc50a13ce8d9d855f9f29e884843ed8717c1e0b2..9b61c75a23556f76898ca2f8b1d26d71b206ca26 100644 (file)
@@ -273,7 +273,6 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
        int i = pmd_index(address);
 
        for (; i < PTRS_PER_PMD; i++, address += PMD_SIZE) {
-               unsigned long entry;
                pmd_t *pmd = pmd_page + pmd_index(address);
 
                if (address >= end) {
@@ -287,9 +286,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
                if (pmd_val(*pmd))
                        continue;
 
-               entry = __PAGE_KERNEL_LARGE|_PAGE_GLOBAL|address;
-               entry &= __supported_pte_mask;
-               set_pmd(pmd, __pmd(entry));
+               set_pte((pte_t *)pmd,
+                       pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
        }
 }
 
@@ -354,17 +352,10 @@ static void __init find_early_table_space(unsigned long end)
         * need roughly 0.5KB per GB.
         */
        start = 0x8000;
-       table_start = find_e820_area(start, end, tables);
+       table_start = find_e820_area(start, end, tables, PAGE_SIZE);
        if (table_start == -1UL)
                panic("Cannot find space for the kernel page tables");
 
-       /*
-        * When you have a lot of RAM like 256GB, early_table will not fit
-        * into 0x8000 range, find_e820_area() will find area after kernel
-        * bss but the table_start is not page aligned, so need to round it
-        * up to avoid overlap with bss:
-        */
-       table_start = round_up(table_start, PAGE_SIZE);
        table_start >>= PAGE_SHIFT;
        table_end = table_start;
 
@@ -420,7 +411,9 @@ void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
                mmu_cr4_features = read_cr4();
        __flush_tlb_all();
 
-       reserve_early(table_start << PAGE_SHIFT, table_end << PAGE_SHIFT);
+       if (!after_bootmem)
+               reserve_early(table_start << PAGE_SHIFT,
+                                table_end << PAGE_SHIFT, "PGTABLE");
 }
 
 #ifndef CONFIG_NUMA
@@ -439,49 +432,6 @@ void __init paging_init(void)
 }
 #endif
 
-/*
- * 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)
-{
-       unsigned long end = address + size;
-
-       BUG_ON(address & ~LARGE_PAGE_MASK);
-       BUG_ON(size & ~LARGE_PAGE_MASK);
-
-       for (; address < end; address += LARGE_PAGE_SIZE) {
-               pgd_t *pgd = pgd_offset_k(address);
-               pud_t *pud;
-               pmd_t *pmd;
-
-               if (pgd_none(*pgd))
-                       continue;
-
-               pud = pud_offset(pgd, address);
-               if (pud_none(*pud))
-                       continue;
-
-               pmd = pmd_offset(pud, address);
-               if (!pmd || pmd_none(*pmd))
-                       continue;
-
-               if (!(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);
-               }
-               set_pmd(pmd, __pmd(0));
-       }
-       __flush_tlb_all();
-}
-
 /*
  * Memory hotplug specific functions
  */
@@ -641,10 +591,17 @@ void mark_rodata_ro(void)
        if (end <= start)
                return;
 
-       set_memory_ro(start, (end - start) >> PAGE_SHIFT);
 
        printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
               (end - start) >> 10);
+       set_memory_ro(start, (end - start) >> PAGE_SHIFT);
+
+       /*
+        * The rodata section (but not the kernel text!) should also be
+        * not-executable.
+        */
+       start = ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
+       set_memory_nx(start, (end - start) >> PAGE_SHIFT);
 
        rodata_test();