8 #include <linux/module.h>
9 #include <linux/signal.h>
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
14 #include <linux/types.h>
15 #include <linux/ptrace.h>
16 #include <linux/mman.h>
24 #include <linux/pci.h>
26 #include <linux/poison.h>
37 #include <asm/processor.h>
38 #include <asm/uaccess.h>
39 #include <asm/pgtable.h>
41 #include <asm/fixmap.h>
46 #include <asm/tlbflush.h>
48 #include <asm/pgalloc.h>
49 #include <asm/sections.h>
50 #include <asm/paravirt.h>
51 #include <asm/setup.h>
52 #include <asm/cacheflush.h>
58 static noinline int do_test_wp_bit(
void);
62 static __init void *alloc_low_page(
void)
68 panic(
"alloc_low_page: ran out of memory");
90 pmd_table = (
pmd_t *)alloc_low_page();
111 if (!(
pmd_val(*pmd) & _PAGE_PRESENT)) {
115 #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK)
122 page_table = (
pte_t *)alloc_low_page();
146 return one_page_table_init(pmd) + pte_idx;
152 #ifdef CONFIG_HIGHMEM
162 if (pmd_idx_kmap_begin != pmd_idx_kmap_end
163 && (vaddr >>
PMD_SHIFT) >= pmd_idx_kmap_begin
164 && (vaddr >>
PMD_SHIFT) <= pmd_idx_kmap_end
171 newpte = alloc_low_page();
185 && lastpte && lastpte + PTRS_PER_PTE != pte);
202 int pgd_idx, pmd_idx;
211 pgd = pgd_base + pgd_idx;
213 for ( ; (pgd_idx <
PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
214 pmd = one_md_table_init(pgd);
218 pte = page_table_kmap_check(one_page_table_init(pmd),
227 static inline int is_kernel_text(
unsigned long addr)
229 if (addr >= (
unsigned long)_text && addr <= (
unsigned long)__init_end)
242 unsigned long page_size_mask)
245 unsigned long last_map_addr =
end;
246 unsigned long start_pfn, end_pfn;
248 int pgd_idx, pmd_idx, pte_ofs;
253 unsigned pages_2m, pages_4k;
279 pages_2m = pages_4k = 0;
282 pgd = pgd_base + pgd_idx;
284 pmd = one_md_table_init(pgd);
288 #ifdef CONFIG_X86_PAE
313 addr2 = (pfn + PTRS_PER_PTE-1) *
PAGE_SIZE +
316 if (is_kernel_text(addr) ||
317 is_kernel_text(addr2))
321 if (mapping_iter == 1)
329 pte = one_page_table_init(pmd);
331 pte_ofs =
pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
333 for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
334 pte++, pfn++, pte_ofs++, addr +=
PAGE_SIZE) {
342 if (is_kernel_text(addr))
346 if (mapping_iter == 1) {
354 if (mapping_iter == 1) {
374 return last_map_addr;
383 vaddr), vaddr), vaddr);
388 unsigned long kmap_vstart;
399 #ifdef CONFIG_HIGHMEM
400 static void __init permanent_kmaps_init(
pgd_t *pgd_base)
420 ClearPageReserved(page);
421 init_page_count(page);
426 void __init add_highpages_with_active_regions(
int nid,
427 unsigned long start_pfn,
unsigned long end_pfn)
432 for_each_free_mem_range(i, nid, &start, &end,
NULL) {
437 for ( ; pfn < e_pfn; pfn++)
443 static inline void permanent_kmaps_init(
pgd_t *pgd_base)
450 unsigned long pfn,
va;
519 permanent_kmaps_init(pgd_base);
526 static unsigned int highmem_pages = -1;
533 static int __init parse_highmem(
char *
arg)
543 #define MSG_HIGHMEM_TOO_BIG \
544 "highmem size (%luMB) is bigger than pages available (%luMB)!\n"
546 #define MSG_LOWMEM_TOO_SMALL \
547 "highmem size (%luMB) results in <64MB lowmem, ignoring it!\n"
558 if (highmem_pages == -1)
560 #ifdef CONFIG_HIGHMEM
561 if (highmem_pages >=
max_pfn) {
576 printk(
KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
580 #define MSG_HIGHMEM_TOO_SMALL \
581 "only %luMB highmem pages available, ignoring highmem size of %luMB!\n"
583 #define MSG_HIGHMEM_TRIMMED \
584 "Warning: only 4GB will be used. Use a HIGHMEM64G enabled kernel!\n"
593 if (highmem_pages == -1)
596 if (highmem_pages + MAXMEM_PFN <
max_pfn)
597 max_pfn = MAXMEM_PFN + highmem_pages;
599 if (highmem_pages + MAXMEM_PFN >
max_pfn) {
605 #ifndef CONFIG_HIGHMEM
614 #ifndef CONFIG_HIGHMEM64G
615 if (
max_pfn > MAX_NONPAE_PFN) {
636 #ifndef CONFIG_NEED_MULTIPLE_NODES
639 #ifdef CONFIG_HIGHMEM
653 sparse_memory_present_with_active_regions(0);
655 #ifdef CONFIG_FLATMEM
695 sparse_memory_present_with_active_regions(
MAX_NUMNODES);
706 static void __init test_wp_bit(
void)
709 "Checking if this processor honours the WP bit even in supervisor mode...");
718 #ifdef CONFIG_X86_WP_WORKS_OK
720 "This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
729 int codesize, reservedpages, datasize, initsize;
734 #ifdef CONFIG_FLATMEM
764 "%dk reserved, %dk data, %dk init, %ldk highmem)\n",
774 " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
775 #ifdef CONFIG_HIGHMEM
776 " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
778 " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
779 " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
780 " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
781 " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
782 " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
786 #ifdef CONFIG_HIGHMEM
795 ((
unsigned long)high_memory - (
unsigned long)
__va(0)) >> 20,
798 ((
unsigned long)&__init_end -
799 (
unsigned long)&__init_begin) >> 10,
802 ((
unsigned long)&_edata - (
unsigned long)&_etext) >> 10,
804 (
unsigned long)&
_text, (
unsigned long)&_etext,
805 ((
unsigned long)&_etext - (
unsigned long)&_text) >> 10);
811 #define __FIXADDR_TOP (-PAGE_SIZE)
812 #ifdef CONFIG_HIGHMEM
816 #define high_memory (-128UL << 20)
821 #ifdef CONFIG_HIGHMEM
826 BUG_ON((
unsigned long)high_memory > VMALLOC_START);
832 #ifdef CONFIG_MEMORY_HOTPLUG
837 unsigned long start_pfn = start >>
PAGE_SHIFT;
840 return __add_pages(nid, zone, start_pfn, nr_pages);
848 static noinline int do_test_wp_bit(
void)
859 :
"=m" (*(
char *)fix_to_virt(FIX_WP_TEST)),
868 #ifdef CONFIG_DEBUG_RODATA
874 void set_kernel_text_rw(
void)
879 if (!kernel_set_to_readonly)
882 pr_debug(
"Set kernel text: %lx - %lx for read write\n",
888 void set_kernel_text_ro(
void)
893 if (!kernel_set_to_readonly)
896 pr_debug(
"Set kernel text: %lx - %lx for read only\n",
902 static void mark_nxdata_nx(
void)
914 if (__supported_pte_mask &
_PAGE_NX)
919 void mark_rodata_ro(
void)
928 kernel_set_to_readonly = 1;
930 #ifdef CONFIG_CPA_DEBUG
940 size = (
unsigned long)__end_rodata - start;
946 #ifdef CONFIG_CPA_DEBUG