[PATCH] x86/boot/compressed: Exclude 'top_pgtable' from relocation

From: Kirill A. Shutemov
Date: Wed May 02 2018 - 12:08:33 EST


startup_64() copies kernel (including .data section) to the new place.
It's required for safe in-place decompression.

This is a problem if the original place is referenced: by mistake I've
put 'top_pgtable' into .data section and the address is loaded into CR3.
If the original place gets overwritten during image decompression the
kernel will crash and the machine will be rebooted.

Move 'top_pgtable' into .pgtable section where the rest of page tables
are. This section is not subject for relocation.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx>
Fixes: e9d0e6330eb8 ("x86/boot/compressed/64: Prepare new top-level page table for trampoline")
---
arch/x86/boot/compressed/head_64.S | 8 ++++++++
arch/x86/boot/compressed/pgtable_64.c | 4 +---
2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index fca012baba19..c433c21703e6 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -649,3 +649,11 @@ boot_stack_end:
.balign 4096
pgtable:
.fill BOOT_PGT_SIZE, 1, 0
+
+/*
+ * The page table is going to be used instead of page table in the trampoline
+ * memory.
+ */
+ .global top_pgtable
+top_pgtable:
+ .fill PAGE_SIZE, 1, 0
diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c
index 32af1cbcd903..3a0578f54550 100644
--- a/arch/x86/boot/compressed/pgtable_64.c
+++ b/arch/x86/boot/compressed/pgtable_64.c
@@ -25,10 +25,8 @@ static char trampoline_save[TRAMPOLINE_32BIT_SIZE];
/*
* The page table is going to be used instead of page table in the trampoline
* memory.
- *
- * It must not be in BSS as BSS is cleared after cleanup_trampoline().
*/
-static char top_pgtable[PAGE_SIZE] __aligned(PAGE_SIZE) __section(.data);
+extern char *top_pgtable;

/*
* Trampoline address will be printed by extract_kernel() for debugging
--
2.17.0