aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-11-16 22:38:51 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2012-11-17 14:59:12 -0500
commite8c57d40519d7226acb8e662f3ab496202ebc7a6 (patch)
tree5ebe8c353345f876af5aea59c65adf371f55b7da /arch/x86/kernel
parent5101730cb0613b91d40b9bb7be6bb023d2f6aa24 (diff)
x86, mm: use pfn_range_is_mapped() with reserve_initrd
We are going to map ram only, so under max_low_pfn_mapped, between 4g and max_pfn_mapped does not mean mapped at all. Use pfn_range_is_mapped() to find out if range is mapped for initrd. That could happen bootloader put initrd in range but user could use memmap to carve some of range out. Also during copying need to use early_memmap to map original initrd for accessing. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Link: http://lkml.kernel.org/r/1353123563-3103-15-git-send-email-yinghai@kernel.org Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/setup.c52
1 files changed, 28 insertions, 24 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d85cbd96525d..bd52f9da17cc 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -317,20 +317,19 @@ static void __init relocate_initrd(void)
317 u64 ramdisk_image = boot_params.hdr.ramdisk_image; 317 u64 ramdisk_image = boot_params.hdr.ramdisk_image;
318 u64 ramdisk_size = boot_params.hdr.ramdisk_size; 318 u64 ramdisk_size = boot_params.hdr.ramdisk_size;
319 u64 area_size = PAGE_ALIGN(ramdisk_size); 319 u64 area_size = PAGE_ALIGN(ramdisk_size);
320 u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
321 u64 ramdisk_here; 320 u64 ramdisk_here;
322 unsigned long slop, clen, mapaddr; 321 unsigned long slop, clen, mapaddr;
323 char *p, *q; 322 char *p, *q;
324 323
325 /* We need to move the initrd down into lowmem */ 324 /* We need to move the initrd down into directly mapped mem */
326 ramdisk_here = memblock_find_in_range(0, end_of_lowmem, area_size, 325 ramdisk_here = memblock_find_in_range(0, PFN_PHYS(max_low_pfn_mapped),
327 PAGE_SIZE); 326 area_size, PAGE_SIZE);
328 327
329 if (!ramdisk_here) 328 if (!ramdisk_here)
330 panic("Cannot find place for new RAMDISK of size %lld\n", 329 panic("Cannot find place for new RAMDISK of size %lld\n",
331 ramdisk_size); 330 ramdisk_size);
332 331
333 /* Note: this includes all the lowmem currently occupied by 332 /* Note: this includes all the mem currently occupied by
334 the initrd, we rely on that fact to keep the data intact. */ 333 the initrd, we rely on that fact to keep the data intact. */
335 memblock_reserve(ramdisk_here, area_size); 334 memblock_reserve(ramdisk_here, area_size);
336 initrd_start = ramdisk_here + PAGE_OFFSET; 335 initrd_start = ramdisk_here + PAGE_OFFSET;
@@ -340,17 +339,7 @@ static void __init relocate_initrd(void)
340 339
341 q = (char *)initrd_start; 340 q = (char *)initrd_start;
342 341
343 /* Copy any lowmem portion of the initrd */ 342 /* Copy the initrd */
344 if (ramdisk_image < end_of_lowmem) {
345 clen = end_of_lowmem - ramdisk_image;
346 p = (char *)__va(ramdisk_image);
347 memcpy(q, p, clen);
348 q += clen;
349 ramdisk_image += clen;
350 ramdisk_size -= clen;
351 }
352
353 /* Copy the highmem portion of the initrd */
354 while (ramdisk_size) { 343 while (ramdisk_size) {
355 slop = ramdisk_image & ~PAGE_MASK; 344 slop = ramdisk_image & ~PAGE_MASK;
356 clen = ramdisk_size; 345 clen = ramdisk_size;
@@ -364,7 +353,7 @@ static void __init relocate_initrd(void)
364 ramdisk_image += clen; 353 ramdisk_image += clen;
365 ramdisk_size -= clen; 354 ramdisk_size -= clen;
366 } 355 }
367 /* high pages is not converted by early_res_to_bootmem */ 356
368 ramdisk_image = boot_params.hdr.ramdisk_image; 357 ramdisk_image = boot_params.hdr.ramdisk_image;
369 ramdisk_size = boot_params.hdr.ramdisk_size; 358 ramdisk_size = boot_params.hdr.ramdisk_size;
370 printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to" 359 printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
@@ -373,13 +362,27 @@ static void __init relocate_initrd(void)
373 ramdisk_here, ramdisk_here + ramdisk_size - 1); 362 ramdisk_here, ramdisk_here + ramdisk_size - 1);
374} 363}
375 364
365static u64 __init get_mem_size(unsigned long limit_pfn)
366{
367 int i;
368 u64 mapped_pages = 0;
369 unsigned long start_pfn, end_pfn;
370
371 for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) {
372 start_pfn = min_t(unsigned long, start_pfn, limit_pfn);
373 end_pfn = min_t(unsigned long, end_pfn, limit_pfn);
374 mapped_pages += end_pfn - start_pfn;
375 }
376
377 return mapped_pages << PAGE_SHIFT;
378}
376static void __init reserve_initrd(void) 379static void __init reserve_initrd(void)
377{ 380{
378 /* Assume only end is not page aligned */ 381 /* Assume only end is not page aligned */
379 u64 ramdisk_image = boot_params.hdr.ramdisk_image; 382 u64 ramdisk_image = boot_params.hdr.ramdisk_image;
380 u64 ramdisk_size = boot_params.hdr.ramdisk_size; 383 u64 ramdisk_size = boot_params.hdr.ramdisk_size;
381 u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); 384 u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
382 u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; 385 u64 mapped_size;
383 386
384 if (!boot_params.hdr.type_of_loader || 387 if (!boot_params.hdr.type_of_loader ||
385 !ramdisk_image || !ramdisk_size) 388 !ramdisk_image || !ramdisk_size)
@@ -387,18 +390,19 @@ static void __init reserve_initrd(void)
387 390
388 initrd_start = 0; 391 initrd_start = 0;
389 392
390 if (ramdisk_size >= (end_of_lowmem>>1)) { 393 mapped_size = get_mem_size(max_low_pfn_mapped);
394 if (ramdisk_size >= (mapped_size>>1))
391 panic("initrd too large to handle, " 395 panic("initrd too large to handle, "
392 "disabling initrd (%lld needed, %lld available)\n", 396 "disabling initrd (%lld needed, %lld available)\n",
393 ramdisk_size, end_of_lowmem>>1); 397 ramdisk_size, mapped_size>>1);
394 }
395 398
396 printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image, 399 printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image,
397 ramdisk_end - 1); 400 ramdisk_end - 1);
398 401
399 402 if (ramdisk_end <= (max_low_pfn_mapped<<PAGE_SHIFT) &&
400 if (ramdisk_end <= end_of_lowmem) { 403 pfn_range_is_mapped(PFN_DOWN(ramdisk_image),
401 /* All in lowmem, easy case */ 404 PFN_DOWN(ramdisk_end))) {
405 /* All are mapped, easy case */
402 /* 406 /*
403 * don't need to reserve again, already reserved early 407 * don't need to reserve again, already reserved early
404 * in i386_start_kernel 408 * in i386_start_kernel