From: Yinghai Lu <yinghai@kernel.org>
To: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@elte.hu>,
"H. Peter Anvin" <hpa@zytor.com>, Jacob Shin <jacob.shin@amd.com>,
Tejun Heo <tj@kernel.org>
Cc: linux-kernel@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>
Subject: [PATCH -v2 13/13] x86, 64bit: Map first 1M ram early before memblock_x86_fill()
Date: Sun, 2 Sep 2012 00:46:59 -0700 [thread overview]
Message-ID: <1346572019-15806-14-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1346572019-15806-1-git-send-email-yinghai@kernel.org>
This one intend to fix bugs:
when efi booting have too many memmap entries, will need to double memblock
memory array or reserved array.
For 64bit, We have low kernel mapping, and high kernel mapping.
high kernel mapping is done early in head_64.S.
low kernel mapping is done in init_memory_mapping.
Now we have max_pfn_mapped actually is for high mapping, so later we
need to get buff for the doubling memblock, but we can not use it.
as __va will return virtual address with low kernel mapping.
The patch will try to map first 1M range, and find early page table space
from BRK.
Also add max_pfn_high_mapped to track high mapped range.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/include/asm/page_types.h | 1 +
arch/x86/include/asm/pgtable.h | 1 +
arch/x86/kernel/head64.c | 2 +-
arch/x86/kernel/setup.c | 2 ++
arch/x86/mm/init.c | 37 +++++++++++++++++++++++++++++++++++--
arch/x86/mm/init_64.c | 7 ++++++-
6 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h
index 54c9787..1903736 100644
--- a/arch/x86/include/asm/page_types.h
+++ b/arch/x86/include/asm/page_types.h
@@ -45,6 +45,7 @@ extern int devmem_is_allowed(unsigned long pagenr);
extern unsigned long max_low_pfn_mapped;
extern unsigned long max_pfn_mapped;
+extern unsigned long max_pfn_high_mapped;
static inline phys_addr_t get_max_mapped(void)
{
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index ae2cabb..c67a684 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -598,6 +598,7 @@ static inline int pgd_none(pgd_t pgd)
extern int direct_gbpages;
void init_mem_mapping(void);
+void early_init_mem_mapping(void);
/* local pte updates need not use xchg for locking */
static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 037df57..b11bde0 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -76,7 +76,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
/* Make NULL pointers segfault */
zap_identity_mappings();
- max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
+ max_pfn_high_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) {
#ifdef CONFIG_EARLY_PRINTK
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 2eb91b7..b942036 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -896,6 +896,8 @@ void __init setup_arch(char **cmdline_p)
reserve_ibft_region();
+ early_init_mem_mapping();
+
/*
* Need to conclude brk, before memblock_x86_fill()
* it could use memblock_find_in_range, could overlap with
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 343d925..c96b731 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -377,8 +377,6 @@ void __init init_mem_mapping(void)
{
unsigned long tables = 0, good_end, end;
- probe_page_size_mask();
-
/*
* Find space for the kernel direct mapping tables.
*
@@ -437,6 +435,41 @@ void __init init_mem_mapping(void)
early_memtest(0, max_pfn_mapped << PAGE_SHIFT);
}
+RESERVE_BRK(early_pgt_alloc, 65536);
+
+void __init early_init_mem_mapping(void)
+{
+ unsigned long tables;
+ phys_addr_t base;
+ unsigned long start = 0, end = ISA_END_ADDRESS;
+
+ probe_page_size_mask();
+
+ if (max_pfn_mapped)
+ return;
+
+ tables = calculate_table_space_size(start, end);
+ base = __pa(extend_brk(tables, PAGE_SIZE));
+
+ pgt_buf_start = base >> PAGE_SHIFT;
+ pgt_buf_end = pgt_buf_start;
+ pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT);
+
+ printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx] prealloc\n",
+ end - 1, pgt_buf_start << PAGE_SHIFT,
+ (pgt_buf_top << PAGE_SHIFT) - 1);
+
+ init_memory_mapping(start, end);
+
+ printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx] final\n",
+ end - 1, pgt_buf_start << PAGE_SHIFT,
+ (pgt_buf_end << PAGE_SHIFT) - 1);
+ /* return not used brk */
+ _brk_end -= (pgt_buf_top - pgt_buf_end) << PAGE_SHIFT;
+
+ pgt_buf_top = 0;
+}
+
/*
* devmem_is_allowed() checks to see if /dev/mem access to a certain address
* is valid. The argument is a physical page number.
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index ab558eb..832ac89 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -286,6 +286,7 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
__init_extra_mapping(phys, size, PAGE_KERNEL_LARGE_NOCACHE);
}
+unsigned long max_pfn_high_mapped;
/*
* The head.S code sets up the kernel high mapping:
*
@@ -302,7 +303,8 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
void __init cleanup_highmap(void)
{
unsigned long vaddr = __START_KERNEL_map;
- unsigned long vaddr_end = __START_KERNEL_map + (max_pfn_mapped << PAGE_SHIFT);
+ unsigned long vaddr_end = __START_KERNEL_map +
+ (max_pfn_high_mapped << PAGE_SHIFT);
unsigned long end = roundup((unsigned long)_brk_end, PMD_SIZE) - 1;
pmd_t *pmd = level2_kernel_pgt;
@@ -312,6 +314,9 @@ void __init cleanup_highmap(void)
if (vaddr < (unsigned long) _text || vaddr > end)
set_pmd(pmd, __pmd(0));
}
+ max_pfn_high_mapped = __pa(end) >> PAGE_SHIFT;
+
+ pr_info("max_pfn_high_mapped: %lx\n", max_pfn_high_mapped);
}
static __ref void *alloc_low_page(unsigned long *phys)
--
1.7.7
next prev parent reply other threads:[~2012-09-02 7:49 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-02 7:46 [PATCH -v2 00/13] x86, mm: init_memory_mapping cleanup Yinghai Lu
2012-09-02 7:46 ` [PATCH -v2 01/13] x86, mm: Add global page_size_mask Yinghai Lu
2012-09-03 5:23 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 02/13] x86, mm: Split out split_mem_range Yinghai Lu
2012-09-03 5:23 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 03/13] x86, mm: Moving init_memory_mapping calling Yinghai Lu
2012-09-03 5:24 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 04/13] x86, mm: Revert back good_end setting for 64bit Yinghai Lu
2012-09-03 5:25 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 05/13] x86, mm: Find early page table only one time Yinghai Lu
2012-09-03 5:27 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 06/13] x86, mm: Separate out calculate_table_space_size() Yinghai Lu
2012-09-03 5:28 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 07/13] x86, mm: Move down two calculate_table_space_size down Yinghai Lu
2012-09-03 5:29 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 08/13] x86: if kernel .text .data .bss are not marked as E820_RAM, complain and fix Yinghai Lu
2012-09-03 5:31 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 09/13] x86: Fixup code testing if a pfn is direct mapped Yinghai Lu
2012-09-03 5:32 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 10/13] x86: Only direct map addresses that are marked as E820_RAM Yinghai Lu
2012-09-03 5:34 ` Pekka Enberg
2012-09-02 7:46 ` [PATCH -v2 11/13] x86/mm: calculate_table_space_size based on memory ranges that are being mapped Yinghai Lu
2012-09-03 5:36 ` Pekka Enberg
2012-09-03 6:21 ` Yinghai Lu
2012-09-02 7:46 ` [PATCH -v2 12/13] x86, mm: Use func pointer to table size calculation and mapping Yinghai Lu
2012-09-03 5:43 ` Pekka Enberg
2012-09-03 6:21 ` Yinghai Lu
2012-09-02 7:46 ` Yinghai Lu [this message]
2012-09-03 5:50 ` [PATCH -v2 13/13] x86, 64bit: Map first 1M ram early before memblock_x86_fill() Pekka Enberg
2012-09-03 6:17 ` Yinghai Lu
2012-09-03 6:26 ` Pekka Enberg
2012-09-03 7:18 ` Yinghai Lu
2012-09-04 2:48 ` Yinghai Lu
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=1346572019-15806-14-git-send-email-yinghai@kernel.org \
--to=yinghai@kernel.org \
--cc=hpa@zytor.com \
--cc=jacob.shin@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
--cc=tj@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome