From: Yinghai Lu <yhlu.kernel@gmail.com>
To: Ingo Molnar <mingo@elte.hu>, Thomas Gleixner <tglx@linutronix.de>,
"H. Peter Anvin" <hpa@zytor.com>,
Suresh Siddha <suresh.b.siddha@intel.com>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: [PATCh] x86: overmapped fix when 4K pages on tail - 64bit
Date: Wed, 9 Jul 2008 20:15:02 -0700 [thread overview]
Message-ID: <200807092015.03004.yhlu.kernel@gmail.com> (raw)
In-Reply-To: <200807080143.27997.yhlu.kernel@gmail.com>
fix phys_pmd_init to make sure not to return big value than end.
also print out range split:1G/2M/4K
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/mm/init_64.c | 106 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 72 insertions(+), 34 deletions(-)
Index: linux-2.6/arch/x86/mm/init_64.c
===================================================================
--- linux-2.6.orig/arch/x86/mm/init_64.c
+++ linux-2.6/arch/x86/mm/init_64.c
@@ -302,11 +302,13 @@ static __meminit void unmap_low_page(voi
early_iounmap(adr, PAGE_SIZE);
}
-static void __meminit
+static unsigned long __meminit
phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end)
{
unsigned pages = 0;
+ unsigned long last_map_addr = end;
int i;
+
pte_t *pte = pte_page + pte_index(addr);
for(i = pte_index(addr); i < PTRS_PER_PTE; i++, addr += PAGE_SIZE, pte++) {
@@ -326,17 +328,20 @@ phys_pte_init(pte_t *pte_page, unsigned
printk(" pte=%p addr=%lx pte=%016lx\n",
pte, addr, pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL).pte);
set_pte(pte, pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL));
+ last_map_addr = (addr & PAGE_MASK) + PAGE_SIZE;
pages++;
}
update_page_count(PG_LEVEL_4K, pages);
+
+ return last_map_addr;
}
-static void __meminit
+static unsigned long __meminit
phys_pte_update(pmd_t *pmd, unsigned long address, unsigned long end)
{
pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd);
- phys_pte_init(pte, address, end);
+ return phys_pte_init(pte, address, end);
}
static unsigned long __meminit
@@ -344,6 +349,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned
unsigned long page_size_mask)
{
unsigned long pages = 0;
+ unsigned long last_map_addr = end;
int i = pmd_index(address);
@@ -362,7 +368,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned
if (pmd_val(*pmd)) {
if (!pmd_large(*pmd))
- phys_pte_update(pmd, address, end);
+ last_map_addr = phys_pte_update(pmd, address,
+ end);
continue;
}
@@ -370,17 +377,18 @@ phys_pmd_init(pmd_t *pmd_page, unsigned
pages++;
set_pte((pte_t *)pmd,
pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
+ last_map_addr = (address & PMD_MASK) + PMD_SIZE;
continue;
}
pte = alloc_low_page(&pte_phys);
- phys_pte_init(pte, address, end);
+ last_map_addr = phys_pte_init(pte, address, end);
unmap_low_page(pte);
pmd_populate_kernel(&init_mm, pmd, __va(pte_phys));
}
update_page_count(PG_LEVEL_2M, pages);
- return address;
+ return last_map_addr;
}
static unsigned long __meminit
@@ -673,6 +681,32 @@ static unsigned long __init kernel_physi
return last_map_addr;
}
+
+struct map_range {
+ unsigned long start;
+ unsigned long end;
+ unsigned page_size_mask;
+};
+
+#define NR_RANGE_MR 5
+
+static int save_mr(struct map_range *mr, int nr_range,
+ unsigned long start_pfn, unsigned long end_pfn,
+ unsigned long page_size_mask)
+{
+
+ if (start_pfn < end_pfn) {
+ if (nr_range >= NR_RANGE_MR)
+ panic("run out of range for init_memory_mapping\n");
+ mr[nr_range].start = start_pfn<<PAGE_SHIFT;
+ mr[nr_range].end = end_pfn<<PAGE_SHIFT;
+ mr[nr_range].page_size_mask = page_size_mask;
+ nr_range++;
+ }
+
+ return nr_range;
+}
+
/*
* Setup the direct mapping of the physical memory at PAGE_OFFSET.
* This runs before bootmem is initialized and gets pages directly from
@@ -681,10 +715,13 @@ static unsigned long __init kernel_physi
unsigned long __init_refok init_memory_mapping(unsigned long start,
unsigned long end)
{
- unsigned long last_map_addr = end;
+ unsigned long last_map_addr = 0;
unsigned long page_size_mask = 0;
unsigned long start_pfn, end_pfn;
+ struct map_range mr[NR_RANGE_MR];
+ int nr_range, i;
+
printk(KERN_INFO "init_memory_mapping\n");
/*
@@ -694,24 +731,22 @@ unsigned long __init_refok init_memory_m
* memory mapped. Unfortunately this is done currently before the
* nodes are discovered.
*/
- if (!after_bootmem) {
+ if (!after_bootmem)
init_gbpages();
- find_early_table_space(end);
- }
if (direct_gbpages)
page_size_mask |= 1 << PG_LEVEL_1G;
if (cpu_has_pse)
page_size_mask |= 1 << PG_LEVEL_2M;
- /* head if not big page aligment ?*/
+ memset(mr, 0, sizeof(mr));
+ nr_range = 0;
+
+ /* head if not big page alignment ?*/
start_pfn = start >> PAGE_SHIFT;
end_pfn = ((start + (PMD_SIZE - 1)) >> PMD_SHIFT)
<< (PMD_SHIFT - PAGE_SHIFT);
- if (start_pfn < end_pfn)
- last_map_addr = kernel_physical_mapping_init(
- start_pfn<<PAGE_SHIFT,
- end_pfn<<PAGE_SHIFT, 0);
+ nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
/* big page (2M) range*/
start_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT)
@@ -720,37 +755,40 @@ unsigned long __init_refok init_memory_m
<< (PUD_SHIFT - PAGE_SHIFT);
if (end_pfn > ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT)))
end_pfn = ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT));
- if (start_pfn < end_pfn)
- last_map_addr = kernel_physical_mapping_init(
- start_pfn<<PAGE_SHIFT,
- end_pfn<<PAGE_SHIFT,
- page_size_mask & (1<<PG_LEVEL_2M));
+ nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
+ page_size_mask & (1<<PG_LEVEL_2M));
/* big page (1G) range */
start_pfn = end_pfn;
end_pfn = (end>>PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT);
- if (start_pfn < end_pfn)
- last_map_addr = kernel_physical_mapping_init(
- start_pfn<<PAGE_SHIFT,
- end_pfn<<PAGE_SHIFT,
- page_size_mask & ((1<<PG_LEVEL_2M)
- | (1<<PG_LEVEL_1G)));
+ nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
+ page_size_mask &
+ ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G)));
/* tail is not big page (1G) alignment */
start_pfn = end_pfn;
end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT);
- if (start_pfn < end_pfn)
- last_map_addr = kernel_physical_mapping_init(
- start_pfn<<PAGE_SHIFT,
- end_pfn<<PAGE_SHIFT,
- page_size_mask & (1<<PG_LEVEL_2M));
+ nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
+ page_size_mask & (1<<PG_LEVEL_2M));
+
/* tail is not big page (2M) alignment */
start_pfn = end_pfn;
end_pfn = end>>PAGE_SHIFT;
- if (start_pfn < end_pfn)
+ nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
+
+ for (i = 0; i < nr_range; i++)
+ printk(KERN_DEBUG " %010lx - %010lx page %s\n",
+ mr[i].start, mr[i].end,
+ (mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":(
+ (mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k"));
+
+ if (!after_bootmem)
+ find_early_table_space(end);
+
+ for (i = 0; i < nr_range; i++)
last_map_addr = kernel_physical_mapping_init(
- start_pfn<<PAGE_SHIFT,
- end_pfn<<PAGE_SHIFT, 0);
+ mr[i].start, mr[i].end,
+ mr[i].page_size_mask);
if (!after_bootmem)
mmu_cr4_features = read_cr4();
next prev parent reply other threads:[~2008-07-10 3:19 UTC|newest]
Thread overview: 84+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-08 8:41 [PATCH] x86: introduce page_size_mask for 64bit Yinghai Lu
2008-07-08 8:43 ` [PATCH] x86: not overmap than end in init_memory_mapping - 64bit Yinghai Lu
2008-07-09 7:38 ` Ingo Molnar
2008-07-09 8:34 ` Ingo Molnar
2008-07-09 8:37 ` Yinghai Lu
2008-07-09 8:46 ` Ingo Molnar
2008-07-09 8:58 ` Yinghai Lu
2008-07-09 10:01 ` Yinghai Lu
2008-07-09 10:30 ` Ingo Molnar
2008-07-09 8:45 ` Ingo Molnar
2008-07-10 3:15 ` Yinghai Lu [this message]
2008-07-10 3:16 ` [PATCH] x86: merge __acpi_map_table Yinghai Lu
2008-07-10 3:17 ` [PATCH] x86: make e820_end return end_of_ram again for 64bit Yinghai Lu
2008-07-10 7:00 ` Ingo Molnar
2008-07-10 11:17 ` [PATCH] x86: e820 remove the range instead of update it to reserved Yinghai Lu
2008-07-11 8:20 ` Ingo Molnar
2008-07-11 3:36 ` [PATCH] x86: save slit Yinghai Lu
2008-07-11 8:22 ` Ingo Molnar
2008-07-11 3:38 ` [PATCH] x86: introduce max_low_pfn_mapped for 64bit Yinghai Lu
2008-07-11 8:26 ` Ingo Molnar
2008-07-11 8:39 ` Yinghai Lu
2008-07-11 8:51 ` Ingo Molnar
2008-07-12 1:41 ` [PATCH] x86: let 32bit use apic_ops too Yinghai Lu
2008-07-12 1:43 ` [PATCH] x86: mach_apicdef.h need to include before smp.h Yinghai Lu
2008-07-12 1:44 ` [PATCH] x86: make read_apic_id return final apicid Yinghai Lu
2008-07-12 8:01 ` [PATCH] x86: make 64bit have get_apic_id Yinghai Lu
2008-07-13 6:28 ` Ingo Molnar
2008-07-13 6:59 ` Ingo Molnar
2008-07-13 7:05 ` Yinghai Lu
2008-07-13 9:23 ` Ingo Molnar
2008-07-13 9:28 ` Ingo Molnar
2008-07-13 16:15 ` Suresh Siddha
2008-07-13 1:19 ` [PATCH] x86: make read_apic_id return final apicid Suresh Siddha
2008-07-13 1:08 ` [PATCH] x86: let 32bit use apic_ops too Suresh Siddha
2008-07-13 2:04 ` Yinghai Lu
2008-07-13 16:28 ` Suresh Siddha
2008-07-13 16:51 ` Maciej W. Rozycki
2008-07-13 17:16 ` Cyrill Gorcunov
2008-07-13 23:46 ` Maciej W. Rozycki
2008-07-14 16:48 ` Cyrill Gorcunov
2008-07-14 17:20 ` Maciej W. Rozycki
2008-07-14 18:09 ` Cyrill Gorcunov
2008-07-14 18:24 ` Maciej W. Rozycki
2008-07-14 18:32 ` Cyrill Gorcunov
2008-07-13 1:43 ` Maciej W. Rozycki
2008-07-13 1:45 ` Yinghai Lu
2008-07-13 1:54 ` Maciej W. Rozycki
2008-07-13 16:43 ` Suresh Siddha
2008-07-13 17:05 ` Maciej W. Rozycki
2008-07-14 5:19 ` [PATCH] x86: let 32bit use apic_ops too - fix Yinghai Lu
2008-07-14 7:12 ` Ingo Molnar
2008-07-14 16:49 ` Suresh Siddha
2008-07-14 17:00 ` Yinghai Lu
2008-07-14 18:03 ` Suresh Siddha
2008-07-18 17:06 ` Ingo Molnar
2008-07-15 17:33 ` Suresh Siddha
2008-07-15 18:10 ` Yinghai Lu
2008-07-15 18:27 ` Suresh Siddha
2008-07-18 17:07 ` Ingo Molnar
2008-07-12 21:30 ` [PATCH] x86: max_low_pfn_mapped fix #1 Yinghai Lu
2008-07-13 9:45 ` Ingo Molnar
2008-07-12 21:31 ` [PATCH] x86: max_low_pfn_mapped fix #2 Yinghai Lu
2008-07-12 21:32 ` [PATCH] x86: max_low_pfn_mapped fix #3 Yinghai Lu
2008-07-13 21:29 ` [PATCH] x86: max_low_pfn_mapped fix #4 Yinghai Lu
2008-07-13 21:30 ` [PATCH] x86: get x86_phys_bits early Yinghai Lu
2008-07-13 21:32 ` [PATCH] x86: make 64bit hpet_set_mapping to use ioremap too Yinghai Lu
2008-07-13 21:50 ` [PATCH] x86: make 64bit hpet_set_mapping to use ioremap too v2 Yinghai Lu
2008-07-10 6:54 ` [PATCH] x86: merge __acpi_map_table Ingo Molnar
2008-07-10 6:53 ` [PATCh] x86: overmapped fix when 4K pages on tail - 64bit Ingo Molnar
2008-07-10 6:57 ` Yinghai Lu
2008-07-10 7:20 ` Ingo Molnar
2008-07-10 7:32 ` Yinghai Lu
2008-07-10 14:16 ` Arjan van de Ven
2008-07-13 14:57 ` Andi Kleen
2008-07-13 15:33 ` Arjan van de Ven
2008-07-13 18:25 ` Andi Kleen
2008-07-13 18:17 ` Yinghai Lu
2008-07-13 18:48 ` Andi Kleen
2008-07-13 19:00 ` Yinghai Lu
2008-07-13 20:32 ` Ingo Molnar
2008-07-13 20:51 ` Andi Kleen
2008-07-14 0:04 ` H. Peter Anvin
2008-07-14 6:39 ` Andi Kleen
2008-07-09 7:38 ` [PATCH] x86: introduce page_size_mask for 64bit Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200807092015.03004.yhlu.kernel@gmail.com \
--to=yhlu.kernel@gmail.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=suresh.b.siddha@intel.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.