diff options
Diffstat (limited to 'arch/x86/mm/init_64.c')
-rw-r--r-- | arch/x86/mm/init_64.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 48623ae628fb..18c6a006e406 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -48,6 +48,18 @@ | |||
48 | #include <asm/numa.h> | 48 | #include <asm/numa.h> |
49 | #include <asm/cacheflush.h> | 49 | #include <asm/cacheflush.h> |
50 | 50 | ||
51 | /* | ||
52 | * PFN of last memory page. | ||
53 | */ | ||
54 | unsigned long end_pfn; | ||
55 | |||
56 | /* | ||
57 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. | ||
58 | * The direct mapping extends to max_pfn_mapped, so that we can directly access | ||
59 | * apertures, ACPI and other tables without having to play with fixmaps. | ||
60 | */ | ||
61 | unsigned long max_pfn_mapped; | ||
62 | |||
51 | static unsigned long dma_reserve __initdata; | 63 | static unsigned long dma_reserve __initdata; |
52 | 64 | ||
53 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 65 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
@@ -808,12 +820,14 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
808 | } | 820 | } |
809 | #endif | 821 | #endif |
810 | 822 | ||
811 | void __init reserve_bootmem_generic(unsigned long phys, unsigned len) | 823 | int __init reserve_bootmem_generic(unsigned long phys, unsigned long len, |
824 | int flags) | ||
812 | { | 825 | { |
813 | #ifdef CONFIG_NUMA | 826 | #ifdef CONFIG_NUMA |
814 | int nid, next_nid; | 827 | int nid, next_nid; |
815 | #endif | 828 | #endif |
816 | unsigned long pfn = phys >> PAGE_SHIFT; | 829 | unsigned long pfn = phys >> PAGE_SHIFT; |
830 | int ret; | ||
817 | 831 | ||
818 | if (pfn >= end_pfn) { | 832 | if (pfn >= end_pfn) { |
819 | /* | 833 | /* |
@@ -821,11 +835,11 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len) | |||
821 | * firmware tables: | 835 | * firmware tables: |
822 | */ | 836 | */ |
823 | if (pfn < max_pfn_mapped) | 837 | if (pfn < max_pfn_mapped) |
824 | return; | 838 | return -EFAULT; |
825 | 839 | ||
826 | printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n", | 840 | printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n", |
827 | phys, len); | 841 | phys, len); |
828 | return; | 842 | return -EFAULT; |
829 | } | 843 | } |
830 | 844 | ||
831 | /* Should check here against the e820 map to avoid double free */ | 845 | /* Should check here against the e820 map to avoid double free */ |
@@ -833,9 +847,13 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len) | |||
833 | nid = phys_to_nid(phys); | 847 | nid = phys_to_nid(phys); |
834 | next_nid = phys_to_nid(phys + len - 1); | 848 | next_nid = phys_to_nid(phys + len - 1); |
835 | if (nid == next_nid) | 849 | if (nid == next_nid) |
836 | reserve_bootmem_node(NODE_DATA(nid), phys, len, BOOTMEM_DEFAULT); | 850 | ret = reserve_bootmem_node(NODE_DATA(nid), phys, len, flags); |
837 | else | 851 | else |
838 | reserve_bootmem(phys, len, BOOTMEM_DEFAULT); | 852 | ret = reserve_bootmem(phys, len, flags); |
853 | |||
854 | if (ret != 0) | ||
855 | return ret; | ||
856 | |||
839 | #else | 857 | #else |
840 | reserve_bootmem(phys, len, BOOTMEM_DEFAULT); | 858 | reserve_bootmem(phys, len, BOOTMEM_DEFAULT); |
841 | #endif | 859 | #endif |
@@ -844,6 +862,8 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len) | |||
844 | dma_reserve += len / PAGE_SIZE; | 862 | dma_reserve += len / PAGE_SIZE; |
845 | set_dma_reserve(dma_reserve); | 863 | set_dma_reserve(dma_reserve); |
846 | } | 864 | } |
865 | |||
866 | return 0; | ||
847 | } | 867 | } |
848 | 868 | ||
849 | int kern_addr_valid(unsigned long addr) | 869 | int kern_addr_valid(unsigned long addr) |