aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/init_64.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-06-25 00:19:20 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-08 07:11:08 -0400
commit7c934d3990aa4d785feddcef700f4c2c4aba2251 (patch)
tree6fb0b00811039239a585e256791d2cf80149cc96 /arch/x86/mm/init_64.c
parent4f9c11dd49fb73e1ec088b27ed6539681a445988 (diff)
x86, 64-bit: create small vmemmap mappings if PSE not available
If PSE is not available, then fall back to 4k page mappings for the vmemmap area. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Cc: xen-devel <xen-devel@lists.xensource.com> Cc: Stephen Tweedie <sct@redhat.com> Cc: Eduardo Habkost <ehabkost@redhat.com> Cc: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/init_64.c')
-rw-r--r--arch/x86/mm/init_64.c62
1 files changed, 40 insertions, 22 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 363751dc3fb8..e62cbdd4e2d9 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -988,7 +988,7 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
988 pmd_t *pmd; 988 pmd_t *pmd;
989 989
990 for (; addr < end; addr = next) { 990 for (; addr < end; addr = next) {
991 next = pmd_addr_end(addr, end); 991 void *p = NULL;
992 992
993 pgd = vmemmap_pgd_populate(addr, node); 993 pgd = vmemmap_pgd_populate(addr, node);
994 if (!pgd) 994 if (!pgd)
@@ -998,33 +998,51 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
998 if (!pud) 998 if (!pud)
999 return -ENOMEM; 999 return -ENOMEM;
1000 1000
1001 pmd = pmd_offset(pud, addr); 1001 if (!cpu_has_pse) {
1002 if (pmd_none(*pmd)) { 1002 next = (addr + PAGE_SIZE) & PAGE_MASK;
1003 pte_t entry; 1003 pmd = vmemmap_pmd_populate(pud, addr, node);
1004 void *p; 1004
1005 if (!pmd)
1006 return -ENOMEM;
1007
1008 p = vmemmap_pte_populate(pmd, addr, node);
1005 1009
1006 p = vmemmap_alloc_block(PMD_SIZE, node);
1007 if (!p) 1010 if (!p)
1008 return -ENOMEM; 1011 return -ENOMEM;
1009 1012
1010 entry = pfn_pte(__pa(p) >> PAGE_SHIFT, 1013 addr_end = addr + PAGE_SIZE;
1011 PAGE_KERNEL_LARGE); 1014 p_end = p + PAGE_SIZE;
1012 set_pmd(pmd, __pmd(pte_val(entry)));
1013
1014 /* check to see if we have contiguous blocks */
1015 if (p_end != p || node_start != node) {
1016 if (p_start)
1017 printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n",
1018 addr_start, addr_end-1, p_start, p_end-1, node_start);
1019 addr_start = addr;
1020 node_start = node;
1021 p_start = p;
1022 }
1023 addr_end = addr + PMD_SIZE;
1024 p_end = p + PMD_SIZE;
1025 } else { 1015 } else {
1026 vmemmap_verify((pte_t *)pmd, node, addr, next); 1016 next = pmd_addr_end(addr, end);
1017
1018 pmd = pmd_offset(pud, addr);
1019 if (pmd_none(*pmd)) {
1020 pte_t entry;
1021
1022 p = vmemmap_alloc_block(PMD_SIZE, node);
1023 if (!p)
1024 return -ENOMEM;
1025
1026 entry = pfn_pte(__pa(p) >> PAGE_SHIFT,
1027 PAGE_KERNEL_LARGE);
1028 set_pmd(pmd, __pmd(pte_val(entry)));
1029
1030 addr_end = addr + PMD_SIZE;
1031 p_end = p + PMD_SIZE;
1032
1033 /* check to see if we have contiguous blocks */
1034 if (p_end != p || node_start != node) {
1035 if (p_start)
1036 printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n",
1037 addr_start, addr_end-1, p_start, p_end-1, node_start);
1038 addr_start = addr;
1039 node_start = node;
1040 p_start = p;
1041 }
1042 } else
1043 vmemmap_verify((pte_t *)pmd, node, addr, next);
1027 } 1044 }
1045
1028 } 1046 }
1029 return 0; 1047 return 0;
1030} 1048}