All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yinghai Lu <yinghai@kernel.org>
To: Kees Cook <keescook@chromium.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>,
	Toshi Kani <toshi.kani@hp.com>,
	Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>,
	David Vrabel <david.vrabel@citrix.com>,
	Wang Nan <wangnan0@huawei.com>,
	linux-kernel@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>
Subject: [PATCH 3/4] x86, 64bit: remove highmap for not needed ranges
Date: Tue, 18 Nov 2014 17:44:16 -0800	[thread overview]
Message-ID: <1416361456-11060-3-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1416361456-11060-1-git-send-email-yinghai@kernel.org>

add cleanup_highmap_late to remove highmap for initmem, around rodata, and
[_brk_end, all_end).

Kernel Layout:

[    0.000000]   .text: [0x01000000-0x0200df88]
[    0.000000] .rodata: [0x02200000-0x02a1dfff]
[    0.000000]   .data: [0x02c00000-0x02e510ff]
[    0.000000]   .init: [0x02e53000-0x03213fff]
[    0.000000]    .bss: [0x03222000-0x0437cfff]
[    0.000000]    .brk: [0x0437d000-0x043a2fff]

Actually used brk:
[    0.270365] memblock_reserve: [0x0000000437d000-0x00000004383fff] flags 0x0 BRK

Before patch:
---[ High Kernel Mapping ]---
---[ High Kernel Mapping ]---
0xffffffff80000000-0xffffffff81000000          16M                           pmd
0xffffffff81000000-0xffffffff82000000          16M     ro         PSE GLB x  pmd
0xffffffff82000000-0xffffffff82011000          68K     ro             GLB x  pte
0xffffffff82011000-0xffffffff82200000        1980K     RW             GLB x  pte
0xffffffff82200000-0xffffffff82a00000           8M     ro         PSE GLB NX pmd
0xffffffff82a00000-0xffffffff82a1e000         120K     ro             GLB NX pte
0xffffffff82a1e000-0xffffffff82c00000        1928K     RW             GLB NX pte
0xffffffff82c00000-0xffffffff82e00000           2M     RW         PSE GLB NX pmd
0xffffffff82e00000-0xffffffff83000000           2M     RW             GLB NX pte
0xffffffff83000000-0xffffffff83200000           2M     RW         PSE GLB NX pmd
0xffffffff83200000-0xffffffff83400000           2M     RW             GLB NX pte
0xffffffff83400000-0xffffffff84400000          16M     RW         PSE GLB NX pmd
0xffffffff84400000-0xffffffffa0000000         444M                           pmd

After patch:
---[ High Kernel Mapping ]---
0xffffffff80000000-0xffffffff81000000          16M                           pmd
0xffffffff81000000-0xffffffff82000000          16M     ro         PSE GLB x  pmd
0xffffffff82000000-0xffffffff82012000          72K     ro             GLB x  pte
0xffffffff82012000-0xffffffff82200000        1976K                           pte
0xffffffff82200000-0xffffffff82a00000           8M     ro         PSE GLB NX pmd
0xffffffff82a00000-0xffffffff82a1e000         120K     ro             GLB NX pte
0xffffffff82a1e000-0xffffffff82c00000        1928K                           pte
0xffffffff82c00000-0xffffffff82e00000           2M     RW         PSE GLB NX pmd
0xffffffff82e00000-0xffffffff82e53000         332K     RW             GLB NX pte
0xffffffff82e53000-0xffffffff83000000        1716K                           pte
0xffffffff83000000-0xffffffff83200000           2M                           pmd
0xffffffff83200000-0xffffffff83214000          80K                           pte
0xffffffff83214000-0xffffffff83400000        1968K     RW             GLB NX pte
0xffffffff83400000-0xffffffff84200000          14M     RW         PSE GLB NX pmd
0xffffffff84200000-0xffffffff84384000        1552K     RW             GLB NX pte
0xffffffff84384000-0xffffffff84400000         496K                           pte
0xffffffff84400000-0xffffffffa0000000         444M                           pmd

So remove some range before rodata with RW+x.

-v4: adapt it to all_end change.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 arch/x86/mm/init_64.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

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
@@ -1101,6 +1101,61 @@ void __init mem_init(void)
 }
 
 #ifdef CONFIG_DEBUG_RODATA
+static void remove_highmap_2m(unsigned long addr)
+{
+	pgd_t *pgd = pgd_offset_k(addr);
+	pud_t *pud = (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr);
+	pmd_t *pmd = (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
+
+	set_pmd(pmd, __pmd(0));
+}
+
+static void remove_highmap_2m_partial(unsigned long addr, unsigned long end)
+{
+	int i;
+	pgd_t *pgd = pgd_offset_k(addr);
+	pud_t *pud = (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr);
+	pmd_t *pmd = (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
+	pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd) + pte_index(addr);
+
+	for (i = pte_index(addr); i < pte_index(end - 1) + 1; i++, pte++)
+		set_pte(pte, __pte(0));
+}
+
+static void cleanup_highmap_late(unsigned long start, unsigned long end)
+{
+	unsigned long addr;
+	unsigned long start_2m_aligned = roundup(start, PMD_SIZE);
+	unsigned long end_2m_aligned = rounddown(end, PMD_SIZE);
+
+	start = PFN_ALIGN(start);
+	end &= PAGE_MASK;
+
+	if (start >= end)
+		return;
+
+	if (start < start_2m_aligned) {
+		unsigned long tmp = min(start_2m_aligned, end);
+
+		set_memory_4k(start, (tmp - start) >> PAGE_SHIFT);
+		remove_highmap_2m_partial(start, tmp);
+	}
+
+	for (addr = start_2m_aligned; addr < end_2m_aligned; addr += PMD_SIZE)
+		remove_highmap_2m(addr);
+
+	if (start <= end_2m_aligned && end_2m_aligned < end) {
+		set_memory_4k(end_2m_aligned,
+				(end - end_2m_aligned) >> PAGE_SHIFT);
+		remove_highmap_2m_partial(end_2m_aligned, end);
+	}
+
+	subtract_range(pfn_highmapped, NR_RANGE,
+			__pa_symbol(start) >> PAGE_SHIFT,
+			__pa_symbol(end) >> PAGE_SHIFT);
+	nr_pfn_highmapped = clean_sort_range(pfn_highmapped, NR_RANGE);
+}
+
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
 
@@ -1149,6 +1204,7 @@ void mark_rodata_ro(void)
 	unsigned long end = (unsigned long) &__end_rodata_hpage_align;
 	unsigned long text_end = PFN_ALIGN(&__stop___ex_table);
 	unsigned long rodata_end = PFN_ALIGN(&__end_rodata);
+	unsigned long data_start = PFN_ALIGN(&_sdata);
 	unsigned long all_end;
 
 	printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
@@ -1172,6 +1228,12 @@ void mark_rodata_ro(void)
 	all_end = roundup(_brk_end, PMD_SIZE);
 	set_memory_nx(rodata_start, (all_end - rodata_start) >> PAGE_SHIFT);
 
+	cleanup_highmap_late(text_end, rodata_start);
+	cleanup_highmap_late(rodata_end, data_start);
+	cleanup_highmap_late(PFN_ALIGN(_brk_end), all_end);
+	cleanup_highmap_late((unsigned long)(&__init_begin),
+				(unsigned long)(&__init_end));
+
 	rodata_test();
 
 #ifdef CONFIG_CPA_DEBUG

  parent reply	other threads:[~2014-11-19  1:44 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-19  1:44 [PATCH 1/3] x86: Fix typo in mark_rodata_ro Yinghai Lu
2014-11-19  1:44 ` [PATCH 2/3] x86, 64bit: add pfn_range_is_highmapped() Yinghai Lu
2014-11-19  1:44 ` Yinghai Lu [this message]
2014-11-19  1:49   ` [PATCH 3/4] x86, 64bit: remove highmap for not needed ranges 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=1416361456-11060-3-git-send-email-yinghai@kernel.org \
    --to=yinghai@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=david.vrabel@citrix.com \
    --cc=hpa@zytor.com \
    --cc=isimatu.yasuaki@jp.fujitsu.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=toshi.kani@hp.com \
    --cc=wangnan0@huawei.com \
    /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.