aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/mm/init_32.c137
1 files changed, 79 insertions, 58 deletions
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index e77459dd38ae..9d36eb9ebd53 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -675,75 +675,96 @@ static int __init parse_highmem(char *arg)
675} 675}
676early_param("highmem", parse_highmem); 676early_param("highmem", parse_highmem);
677 677
678#define MSG_HIGHMEM_TOO_BIG \
679 "highmem size (%luMB) is bigger than pages available (%luMB)!\n"
680
681#define MSG_LOWMEM_TOO_SMALL \
682 "highmem size (%luMB) results in <64MB lowmem, ignoring it!\n"
678/* 683/*
679 * Determine low and high memory ranges: 684 * All of RAM fits into lowmem - but if user wants highmem
685 * artificially via the highmem=x boot parameter then create
686 * it:
680 */ 687 */
681void __init find_low_pfn_range(void) 688void __init lowmem_pfn_init(void)
682{ 689{
683 /* it could update max_pfn */ 690 if (highmem_pages == -1)
684 691 highmem_pages = 0;
685 /* max_low_pfn is 0, we already have early_res support */ 692#ifdef CONFIG_HIGHMEM
686 693 if (highmem_pages >= max_pfn) {
687 max_low_pfn = max_pfn; 694 printk(KERN_ERR MSG_HIGHMEM_TOO_BIG,
688 if (max_low_pfn > MAXMEM_PFN) { 695 pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
689 if (highmem_pages == -1) 696 highmem_pages = 0;
690 highmem_pages = max_pfn - MAXMEM_PFN; 697 }
691 if (highmem_pages + MAXMEM_PFN < max_pfn) 698 if (highmem_pages) {
692 max_pfn = MAXMEM_PFN + highmem_pages; 699 if (max_low_pfn - highmem_pages < 64*1024*1024/PAGE_SIZE) {
693 if (highmem_pages + MAXMEM_PFN > max_pfn) { 700 printk(KERN_ERR MSG_LOWMEM_TOO_SMALL,
694 printk(KERN_WARNING "only %luMB highmem pages "
695 "available, ignoring highmem size of %luMB.\n",
696 pages_to_mb(max_pfn - MAXMEM_PFN),
697 pages_to_mb(highmem_pages)); 701 pages_to_mb(highmem_pages));
698 highmem_pages = 0; 702 highmem_pages = 0;
699 } 703 }
700 max_low_pfn = MAXMEM_PFN; 704 max_low_pfn -= highmem_pages;
705 }
706#else
707 if (highmem_pages)
708 printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
709#endif
710}
711
712#define MSG_HIGHMEM_TOO_SMALL \
713 "only %luMB highmem pages available, ignoring highmem size of %luMB!\n"
714
715#define MSG_HIGHMEM_TRIMMED \
716 "Warning: only 4GB will be used. Use a HIGHMEM64G enabled kernel!\n"
717/*
718 * We have more RAM than fits into lowmem - we try to put it into
719 * highmem, also taking the highmem=x boot parameter into account:
720 */
721void __init highmem_pfn_init(void)
722{
723 if (highmem_pages == -1)
724 highmem_pages = max_pfn - MAXMEM_PFN;
725
726 if (highmem_pages + MAXMEM_PFN < max_pfn)
727 max_pfn = MAXMEM_PFN + highmem_pages;
728
729 if (highmem_pages + MAXMEM_PFN > max_pfn) {
730 printk(KERN_WARNING MSG_HIGHMEM_TOO_SMALL,
731 pages_to_mb(max_pfn - MAXMEM_PFN),
732 pages_to_mb(highmem_pages));
733 highmem_pages = 0;
734 }
735 max_low_pfn = MAXMEM_PFN;
701#ifndef CONFIG_HIGHMEM 736#ifndef CONFIG_HIGHMEM
702 /* Maximum memory usable is what is directly addressable */ 737 /* Maximum memory usable is what is directly addressable */
703 printk(KERN_WARNING "Warning only %ldMB will be used.\n", 738 printk(KERN_WARNING "Warning only %ldMB will be used.\n", MAXMEM>>20);
704 MAXMEM>>20); 739 if (max_pfn > MAX_NONPAE_PFN)
705 if (max_pfn > MAX_NONPAE_PFN) 740 printk(KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n");
706 printk(KERN_WARNING 741 else
707 "Use a HIGHMEM64G enabled kernel.\n"); 742 printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
708 else 743 max_pfn = MAXMEM_PFN;
709 printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
710 max_pfn = MAXMEM_PFN;
711#else /* !CONFIG_HIGHMEM */ 744#else /* !CONFIG_HIGHMEM */
712#ifndef CONFIG_HIGHMEM64G 745#ifndef CONFIG_HIGHMEM64G
713 if (max_pfn > MAX_NONPAE_PFN) { 746 if (max_pfn > MAX_NONPAE_PFN) {
714 max_pfn = MAX_NONPAE_PFN; 747 max_pfn = MAX_NONPAE_PFN;
715 printk(KERN_WARNING "Warning only 4GB will be used." 748 printk(KERN_WARNING MSG_HIGHMEM_TRIMMED);
716 "Use a HIGHMEM64G enabled kernel.\n"); 749 }
717 }
718#endif /* !CONFIG_HIGHMEM64G */ 750#endif /* !CONFIG_HIGHMEM64G */
719#endif /* !CONFIG_HIGHMEM */ 751#endif /* !CONFIG_HIGHMEM */
720 } else { 752}
721 if (highmem_pages == -1) 753
722 highmem_pages = 0; 754/*
723#ifdef CONFIG_HIGHMEM 755 * Determine low and high memory ranges:
724 if (highmem_pages >= max_pfn) { 756 */
725 printk(KERN_ERR "highmem size specified (%luMB) is " 757void __init find_low_pfn_range(void)
726 "bigger than pages available (%luMB)!.\n", 758{
727 pages_to_mb(highmem_pages), 759 /* it could update max_pfn */
728 pages_to_mb(max_pfn)); 760
729 highmem_pages = 0; 761 /* max_low_pfn is 0, we already have early_res support */
730 } 762 max_low_pfn = max_pfn;
731 if (highmem_pages) { 763
732 if (max_low_pfn - highmem_pages < 764 if (max_low_pfn > MAXMEM_PFN)
733 64*1024*1024/PAGE_SIZE){ 765 highmem_pfn_init();
734 printk(KERN_ERR "highmem size %luMB results in " 766 else
735 "smaller than 64MB lowmem, ignoring it.\n" 767 lowmem_pfn_init();
736 , pages_to_mb(highmem_pages));
737 highmem_pages = 0;
738 }
739 max_low_pfn -= highmem_pages;
740 }
741#else
742 if (highmem_pages)
743 printk(KERN_ERR "ignoring highmem size on non-highmem"
744 " kernel!\n");
745#endif
746 }
747} 768}
748 769
749#ifndef CONFIG_NEED_MULTIPLE_NODES 770#ifndef CONFIG_NEED_MULTIPLE_NODES