diff options
Diffstat (limited to 'arch/x86/mm/init_64.c')
-rw-r--r-- | arch/x86/mm/init_64.c | 74 |
1 files changed, 57 insertions, 17 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 1ff7906a9a4d..32ba13b0f818 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -135,7 +135,7 @@ static __init void *spp_getpage(void) | |||
135 | return ptr; | 135 | return ptr; |
136 | } | 136 | } |
137 | 137 | ||
138 | static __init void | 138 | static void |
139 | set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) | 139 | set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) |
140 | { | 140 | { |
141 | pgd_t *pgd; | 141 | pgd_t *pgd; |
@@ -173,7 +173,7 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) | |||
173 | new_pte = pfn_pte(phys >> PAGE_SHIFT, prot); | 173 | new_pte = pfn_pte(phys >> PAGE_SHIFT, prot); |
174 | 174 | ||
175 | pte = pte_offset_kernel(pmd, vaddr); | 175 | pte = pte_offset_kernel(pmd, vaddr); |
176 | if (!pte_none(*pte) && | 176 | if (!pte_none(*pte) && pte_val(new_pte) && |
177 | pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask)) | 177 | pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask)) |
178 | pte_ERROR(*pte); | 178 | pte_ERROR(*pte); |
179 | set_pte(pte, new_pte); | 179 | set_pte(pte, new_pte); |
@@ -214,8 +214,7 @@ void __init cleanup_highmap(void) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | /* NOTE: this is meant to be run only at boot */ | 216 | /* NOTE: this is meant to be run only at boot */ |
217 | void __init | 217 | void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) |
218 | __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) | ||
219 | { | 218 | { |
220 | unsigned long address = __fix_to_virt(idx); | 219 | unsigned long address = __fix_to_virt(idx); |
221 | 220 | ||
@@ -621,15 +620,6 @@ void __init paging_init(void) | |||
621 | /* | 620 | /* |
622 | * Memory hotplug specific functions | 621 | * Memory hotplug specific functions |
623 | */ | 622 | */ |
624 | void online_page(struct page *page) | ||
625 | { | ||
626 | ClearPageReserved(page); | ||
627 | init_page_count(page); | ||
628 | __free_page(page); | ||
629 | totalram_pages++; | ||
630 | num_physpages++; | ||
631 | } | ||
632 | |||
633 | #ifdef CONFIG_MEMORY_HOTPLUG | 623 | #ifdef CONFIG_MEMORY_HOTPLUG |
634 | /* | 624 | /* |
635 | * Memory is added always to NORMAL zone. This means you will never get | 625 | * Memory is added always to NORMAL zone. This means you will never get |
@@ -664,6 +654,26 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); | |||
664 | 654 | ||
665 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 655 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
666 | 656 | ||
657 | /* | ||
658 | * devmem_is_allowed() checks to see if /dev/mem access to a certain address | ||
659 | * is valid. The argument is a physical page number. | ||
660 | * | ||
661 | * | ||
662 | * On x86, access has to be given to the first megabyte of ram because that area | ||
663 | * contains bios code and data regions used by X and dosemu and similar apps. | ||
664 | * Access has to be given to non-kernel-ram areas as well, these contain the PCI | ||
665 | * mmio resources as well as potential bios/acpi data regions. | ||
666 | */ | ||
667 | int devmem_is_allowed(unsigned long pagenr) | ||
668 | { | ||
669 | if (pagenr <= 256) | ||
670 | return 1; | ||
671 | if (!page_is_ram(pagenr)) | ||
672 | return 1; | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | |||
667 | static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, | 677 | static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, |
668 | kcore_modules, kcore_vsyscall; | 678 | kcore_modules, kcore_vsyscall; |
669 | 679 | ||
@@ -791,7 +801,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
791 | void __init reserve_bootmem_generic(unsigned long phys, unsigned len) | 801 | void __init reserve_bootmem_generic(unsigned long phys, unsigned len) |
792 | { | 802 | { |
793 | #ifdef CONFIG_NUMA | 803 | #ifdef CONFIG_NUMA |
794 | int nid = phys_to_nid(phys); | 804 | int nid, next_nid; |
795 | #endif | 805 | #endif |
796 | unsigned long pfn = phys >> PAGE_SHIFT; | 806 | unsigned long pfn = phys >> PAGE_SHIFT; |
797 | 807 | ||
@@ -810,10 +820,16 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len) | |||
810 | 820 | ||
811 | /* Should check here against the e820 map to avoid double free */ | 821 | /* Should check here against the e820 map to avoid double free */ |
812 | #ifdef CONFIG_NUMA | 822 | #ifdef CONFIG_NUMA |
813 | reserve_bootmem_node(NODE_DATA(nid), phys, len, BOOTMEM_DEFAULT); | 823 | nid = phys_to_nid(phys); |
824 | next_nid = phys_to_nid(phys + len - 1); | ||
825 | if (nid == next_nid) | ||
826 | reserve_bootmem_node(NODE_DATA(nid), phys, len, BOOTMEM_DEFAULT); | ||
827 | else | ||
828 | reserve_bootmem(phys, len, BOOTMEM_DEFAULT); | ||
814 | #else | 829 | #else |
815 | reserve_bootmem(phys, len, BOOTMEM_DEFAULT); | 830 | reserve_bootmem(phys, len, BOOTMEM_DEFAULT); |
816 | #endif | 831 | #endif |
832 | |||
817 | if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { | 833 | if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { |
818 | dma_reserve += len / PAGE_SIZE; | 834 | dma_reserve += len / PAGE_SIZE; |
819 | set_dma_reserve(dma_reserve); | 835 | set_dma_reserve(dma_reserve); |
@@ -907,6 +923,10 @@ const char *arch_vma_name(struct vm_area_struct *vma) | |||
907 | /* | 923 | /* |
908 | * Initialise the sparsemem vmemmap using huge-pages at the PMD level. | 924 | * Initialise the sparsemem vmemmap using huge-pages at the PMD level. |
909 | */ | 925 | */ |
926 | static long __meminitdata addr_start, addr_end; | ||
927 | static void __meminitdata *p_start, *p_end; | ||
928 | static int __meminitdata node_start; | ||
929 | |||
910 | int __meminit | 930 | int __meminit |
911 | vmemmap_populate(struct page *start_page, unsigned long size, int node) | 931 | vmemmap_populate(struct page *start_page, unsigned long size, int node) |
912 | { | 932 | { |
@@ -941,12 +961,32 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node) | |||
941 | PAGE_KERNEL_LARGE); | 961 | PAGE_KERNEL_LARGE); |
942 | set_pmd(pmd, __pmd(pte_val(entry))); | 962 | set_pmd(pmd, __pmd(pte_val(entry))); |
943 | 963 | ||
944 | printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n", | 964 | /* check to see if we have contiguous blocks */ |
945 | addr, addr + PMD_SIZE - 1, p, node); | 965 | if (p_end != p || node_start != node) { |
966 | if (p_start) | ||
967 | printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n", | ||
968 | addr_start, addr_end-1, p_start, p_end-1, node_start); | ||
969 | addr_start = addr; | ||
970 | node_start = node; | ||
971 | p_start = p; | ||
972 | } | ||
973 | addr_end = addr + PMD_SIZE; | ||
974 | p_end = p + PMD_SIZE; | ||
946 | } else { | 975 | } else { |
947 | vmemmap_verify((pte_t *)pmd, node, addr, next); | 976 | vmemmap_verify((pte_t *)pmd, node, addr, next); |
948 | } | 977 | } |
949 | } | 978 | } |
950 | return 0; | 979 | return 0; |
951 | } | 980 | } |
981 | |||
982 | void __meminit vmemmap_populate_print_last(void) | ||
983 | { | ||
984 | if (p_start) { | ||
985 | printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n", | ||
986 | addr_start, addr_end-1, p_start, p_end-1, node_start); | ||
987 | p_start = NULL; | ||
988 | p_end = NULL; | ||
989 | node_start = 0; | ||
990 | } | ||
991 | } | ||
952 | #endif | 992 | #endif |