diff options
author | Yinghai Lu <yinghai@kernel.org> | 2008-10-28 15:39:23 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-28 15:54:47 -0400 |
commit | f96f57d91c2df75011d1e260c23edca429f37361 (patch) | |
tree | 21f416671c67afcf6c405f59dc955fddbfe0ff47 /arch/x86/mm | |
parent | 87c6f40128f92621698f97a62d2ead5184d1dd97 (diff) |
x86: fix init_memory_mapping for [dc000000 - e0000000) - v2
Impact: change over-mapping to precise mapping, fix /proc/meminfo output
v2: fix less than 1G ram system handling
when gart aperture is 0xdc000000 - 0xe0000000
it return 0xc0000000 - 0xe0000000
that is not right.
this patch fix that will get exact mapping
on 256g sytem with that aperture after patch
LBSuse:~ # cat /proc/meminfo
MemTotal: 264742432 kB
MemFree: 263920628 kB
Buffers: 1416 kB
Cached: 24468 kB
...
DirectMap4k: 5760 kB
DirectMap2M: 3205120 kB
DirectMap1G: 265289728 kB
it is consistent to
LBSuse:~ # cat /sys/kernel/debug/kernel_page_tables
..
---[ Low Kernel Mapping ]---
0xffff880000000000-0xffff880000200000 2M RW GLB x pte
0xffff880000200000-0xffff880040000000 1022M RW PSE GLB x pmd
0xffff880040000000-0xffff8800c0000000 2G RW PSE GLB NX pud
0xffff8800c0000000-0xffff8800d7e00000 382M RW PSE GLB NX pmd
0xffff8800d7e00000-0xffff8800d7fa0000 1664K RW GLB NX pte
0xffff8800d7fa0000-0xffff8800d8000000 384K pte
0xffff8800d8000000-0xffff8800dc000000 64M pmd
0xffff8800dc000000-0xffff8800e0000000 64M RW PSE GLB NX pmd
0xffff8800e0000000-0xffff880100000000 512M pmd
0xffff880100000000-0xffff880800000000 28G RW PSE GLB NX pud
0xffff880800000000-0xffff880824600000 582M RW PSE GLB NX pmd
0xffff880824600000-0xffff8808247f0000 1984K RW GLB NX pte
0xffff8808247f0000-0xffff880824800000 64K RW PCD GLB NX pte
0xffff880824800000-0xffff880840000000 440M RW PSE GLB NX pmd
0xffff880840000000-0xffff884000000000 223G RW PSE GLB NX pud
0xffff884000000000-0xffff884028000000 640M RW PSE GLB NX pmd
0xffff884028000000-0xffff884040000000 384M pmd
0xffff884040000000-0xffff888000000000 255G pud
0xffff888000000000-0xffffc20000000000 58880G pgd
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/init_64.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index ad38648bddbd..ebe1811e5b1e 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -671,12 +671,13 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, | |||
671 | unsigned long last_map_addr = 0; | 671 | unsigned long last_map_addr = 0; |
672 | unsigned long page_size_mask = 0; | 672 | unsigned long page_size_mask = 0; |
673 | unsigned long start_pfn, end_pfn; | 673 | unsigned long start_pfn, end_pfn; |
674 | unsigned long pos; | ||
674 | 675 | ||
675 | struct map_range mr[NR_RANGE_MR]; | 676 | struct map_range mr[NR_RANGE_MR]; |
676 | int nr_range, i; | 677 | int nr_range, i; |
677 | int use_pse, use_gbpages; | 678 | int use_pse, use_gbpages; |
678 | 679 | ||
679 | printk(KERN_INFO "init_memory_mapping\n"); | 680 | printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); |
680 | 681 | ||
681 | /* | 682 | /* |
682 | * Find space for the kernel direct mapping tables. | 683 | * Find space for the kernel direct mapping tables. |
@@ -710,35 +711,50 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, | |||
710 | 711 | ||
711 | /* head if not big page alignment ?*/ | 712 | /* head if not big page alignment ?*/ |
712 | start_pfn = start >> PAGE_SHIFT; | 713 | start_pfn = start >> PAGE_SHIFT; |
713 | end_pfn = ((start + (PMD_SIZE - 1)) >> PMD_SHIFT) | 714 | pos = start_pfn << PAGE_SHIFT; |
715 | end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT) | ||
714 | << (PMD_SHIFT - PAGE_SHIFT); | 716 | << (PMD_SHIFT - PAGE_SHIFT); |
715 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); | 717 | if (start_pfn < end_pfn) { |
718 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); | ||
719 | pos = end_pfn << PAGE_SHIFT; | ||
720 | } | ||
716 | 721 | ||
717 | /* big page (2M) range*/ | 722 | /* big page (2M) range*/ |
718 | start_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT) | 723 | start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT) |
719 | << (PMD_SHIFT - PAGE_SHIFT); | 724 | << (PMD_SHIFT - PAGE_SHIFT); |
720 | end_pfn = ((start + (PUD_SIZE - 1))>>PUD_SHIFT) | 725 | end_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT) |
721 | << (PUD_SHIFT - PAGE_SHIFT); | 726 | << (PUD_SHIFT - PAGE_SHIFT); |
722 | if (end_pfn > ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT))) | 727 | if (end_pfn > ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT))) |
723 | end_pfn = ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT)); | 728 | end_pfn = ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT)); |
724 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | 729 | if (start_pfn < end_pfn) { |
725 | page_size_mask & (1<<PG_LEVEL_2M)); | 730 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, |
731 | page_size_mask & (1<<PG_LEVEL_2M)); | ||
732 | pos = end_pfn << PAGE_SHIFT; | ||
733 | } | ||
726 | 734 | ||
727 | /* big page (1G) range */ | 735 | /* big page (1G) range */ |
728 | start_pfn = end_pfn; | 736 | start_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT) |
729 | end_pfn = (end>>PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); | 737 | << (PUD_SHIFT - PAGE_SHIFT); |
730 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | 738 | end_pfn = (end >> PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); |
739 | if (start_pfn < end_pfn) { | ||
740 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | ||
731 | page_size_mask & | 741 | page_size_mask & |
732 | ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G))); | 742 | ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G))); |
743 | pos = end_pfn << PAGE_SHIFT; | ||
744 | } | ||
733 | 745 | ||
734 | /* tail is not big page (1G) alignment */ | 746 | /* tail is not big page (1G) alignment */ |
735 | start_pfn = end_pfn; | 747 | start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT) |
736 | end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); | 748 | << (PMD_SHIFT - PAGE_SHIFT); |
737 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | 749 | end_pfn = (end >> PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); |
738 | page_size_mask & (1<<PG_LEVEL_2M)); | 750 | if (start_pfn < end_pfn) { |
751 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | ||
752 | page_size_mask & (1<<PG_LEVEL_2M)); | ||
753 | pos = end_pfn << PAGE_SHIFT; | ||
754 | } | ||
739 | 755 | ||
740 | /* tail is not big page (2M) alignment */ | 756 | /* tail is not big page (2M) alignment */ |
741 | start_pfn = end_pfn; | 757 | start_pfn = pos>>PAGE_SHIFT; |
742 | end_pfn = end>>PAGE_SHIFT; | 758 | end_pfn = end>>PAGE_SHIFT; |
743 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); | 759 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); |
744 | 760 | ||