diff options
Diffstat (limited to 'mm/sparse.c')
-rw-r--r-- | mm/sparse.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/mm/sparse.c b/mm/sparse.c index 36511c7b5e2c..7a3650923d9a 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/dma.h> | 12 | #include <asm/dma.h> |
13 | #include <asm/pgalloc.h> | 13 | #include <asm/pgalloc.h> |
14 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
15 | #include "internal.h" | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Permanent SPARSEMEM data: | 18 | * Permanent SPARSEMEM data: |
@@ -147,22 +148,41 @@ static inline int sparse_early_nid(struct mem_section *section) | |||
147 | return (section->section_mem_map >> SECTION_NID_SHIFT); | 148 | return (section->section_mem_map >> SECTION_NID_SHIFT); |
148 | } | 149 | } |
149 | 150 | ||
150 | /* Record a memory area against a node. */ | 151 | /* Validate the physical addressing limitations of the model */ |
151 | void __init memory_present(int nid, unsigned long start, unsigned long end) | 152 | void __meminit mminit_validate_memmodel_limits(unsigned long *start_pfn, |
153 | unsigned long *end_pfn) | ||
152 | { | 154 | { |
153 | unsigned long max_arch_pfn = 1UL << (MAX_PHYSMEM_BITS-PAGE_SHIFT); | 155 | unsigned long max_sparsemem_pfn = 1UL << (MAX_PHYSMEM_BITS-PAGE_SHIFT); |
154 | unsigned long pfn; | ||
155 | 156 | ||
156 | /* | 157 | /* |
157 | * Sanity checks - do not allow an architecture to pass | 158 | * Sanity checks - do not allow an architecture to pass |
158 | * in larger pfns than the maximum scope of sparsemem: | 159 | * in larger pfns than the maximum scope of sparsemem: |
159 | */ | 160 | */ |
160 | if (start >= max_arch_pfn) | 161 | if (*start_pfn > max_sparsemem_pfn) { |
161 | return; | 162 | mminit_dprintk(MMINIT_WARNING, "pfnvalidation", |
162 | if (end >= max_arch_pfn) | 163 | "Start of range %lu -> %lu exceeds SPARSEMEM max %lu\n", |
163 | end = max_arch_pfn; | 164 | *start_pfn, *end_pfn, max_sparsemem_pfn); |
165 | WARN_ON_ONCE(1); | ||
166 | *start_pfn = max_sparsemem_pfn; | ||
167 | *end_pfn = max_sparsemem_pfn; | ||
168 | } | ||
169 | |||
170 | if (*end_pfn > max_sparsemem_pfn) { | ||
171 | mminit_dprintk(MMINIT_WARNING, "pfnvalidation", | ||
172 | "End of range %lu -> %lu exceeds SPARSEMEM max %lu\n", | ||
173 | *start_pfn, *end_pfn, max_sparsemem_pfn); | ||
174 | WARN_ON_ONCE(1); | ||
175 | *end_pfn = max_sparsemem_pfn; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | /* Record a memory area against a node. */ | ||
180 | void __init memory_present(int nid, unsigned long start, unsigned long end) | ||
181 | { | ||
182 | unsigned long pfn; | ||
164 | 183 | ||
165 | start &= PAGE_SECTION_MASK; | 184 | start &= PAGE_SECTION_MASK; |
185 | mminit_validate_memmodel_limits(&start, &end); | ||
166 | for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { | 186 | for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { |
167 | unsigned long section = pfn_to_section_nr(pfn); | 187 | unsigned long section = pfn_to_section_nr(pfn); |
168 | struct mem_section *ms; | 188 | struct mem_section *ms; |
@@ -187,6 +207,7 @@ unsigned long __init node_memmap_size_bytes(int nid, unsigned long start_pfn, | |||
187 | unsigned long pfn; | 207 | unsigned long pfn; |
188 | unsigned long nr_pages = 0; | 208 | unsigned long nr_pages = 0; |
189 | 209 | ||
210 | mminit_validate_memmodel_limits(&start_pfn, &end_pfn); | ||
190 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { | 211 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { |
191 | if (nid != early_pfn_to_nid(pfn)) | 212 | if (nid != early_pfn_to_nid(pfn)) |
192 | continue; | 213 | continue; |