From edc7c6ee64ba987783ec70628f5eb225477ac7cc Mon Sep 17 00:00:00 2001 From: Hans van Kranenburg Date: Wed, 12 Dec 2018 00:10:19 +0100 Subject: [PATCH] [x86] Fix booting as Xen dom0 This patch is from the tip repo, and will show up in 4.19 later. --- debian/changelog | 3 + .../x86/x86-mm-Fix-guard-hole-handling.patch | 114 ++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 118 insertions(+) create mode 100644 debian/patches/bugfix/x86/x86-mm-Fix-guard-hole-handling.patch diff --git a/debian/changelog b/debian/changelog index a5d4c95d8..144408797 100644 --- a/debian/changelog +++ b/debian/changelog @@ -59,6 +59,9 @@ linux (4.19.8-1) UNRELEASED; urgency=medium * Add patches to build libbpf.so with SONAME, link against libelf * Add versioned libbpf, libbpf-dev package (Closes: #914428) + [ Hans van Kranenburg ] + * [x86] Add patch to repair booting as Xen dom0 (Closes: #914951) + -- Uwe Kleine-König Wed, 28 Nov 2018 12:20:46 +0100 linux (4.19.5-1~exp1) experimental; urgency=medium diff --git a/debian/patches/bugfix/x86/x86-mm-Fix-guard-hole-handling.patch b/debian/patches/bugfix/x86/x86-mm-Fix-guard-hole-handling.patch new file mode 100644 index 000000000..e92a47b40 --- /dev/null +++ b/debian/patches/bugfix/x86/x86-mm-Fix-guard-hole-handling.patch @@ -0,0 +1,114 @@ +From: "Kirill A. Shutemov" +Date: Fri, 30 Nov 2018 23:23:27 +0300 +Subject: x86/mm: Fix guard hole handling +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?id=16877a5570e0c5f4270d5b17f9bab427bcae9514 + +There is a guard hole at the beginning of the kernel address space, also +used by hypervisors. It occupies 16 PGD entries. + +This reserved range is not defined explicitely, it is calculated relative +to other entities: direct mapping and user space ranges. + +The calculation got broken by recent changes of the kernel memory layout: +LDT remap range is now mapped before direct mapping and makes the +calculation invalid. + +The breakage leads to crash on Xen dom0 boot[1]. + +Define the reserved range explicitely. It's part of kernel ABI (hypervisors +expect it to be stable) and must not depend on changes in the rest of +kernel memory layout. + +[1] https://lists.xenproject.org/archives/html/xen-devel/2018-11/msg03313.html + +Fixes: d52888aa2753 ("x86/mm: Move LDT remap out of KASLR region on 5-level paging") +Reported-by: Hans van Kranenburg +Signed-off-by: Kirill A. Shutemov +Signed-off-by: Thomas Gleixner +Tested-by: Hans van Kranenburg +Reviewed-by: Juergen Gross +Cc: bp@alien8.de +Cc: hpa@zytor.com +Cc: dave.hansen@linux.intel.com +Cc: luto@kernel.org +Cc: peterz@infradead.org +Cc: boris.ostrovsky@oracle.com +Cc: bhe@redhat.com +Cc: linux-mm@kvack.org +Cc: xen-devel@lists.xenproject.org +Link: https://lkml.kernel.org/r/20181130202328.65359-2-kirill.shutemov@linux.intel.com +--- + arch/x86/include/asm/pgtable_64_types.h | 5 +++++ + arch/x86/mm/dump_pagetables.c | 8 ++++---- + arch/x86/xen/mmu_pv.c | 11 ++++++----- + 3 files changed, 15 insertions(+), 9 deletions(-) + +diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h +index 84bd9bdc1987..88bca456da99 100644 +--- a/arch/x86/include/asm/pgtable_64_types.h ++++ b/arch/x86/include/asm/pgtable_64_types.h +@@ -111,6 +111,11 @@ extern unsigned int ptrs_per_p4d; + */ + #define MAXMEM (1UL << MAX_PHYSMEM_BITS) + ++#define GUARD_HOLE_PGD_ENTRY -256UL ++#define GUARD_HOLE_SIZE (16UL << PGDIR_SHIFT) ++#define GUARD_HOLE_BASE_ADDR (GUARD_HOLE_PGD_ENTRY << PGDIR_SHIFT) ++#define GUARD_HOLE_END_ADDR (GUARD_HOLE_BASE_ADDR + GUARD_HOLE_SIZE) ++ + #define LDT_PGD_ENTRY -240UL + #define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT) + #define LDT_END_ADDR (LDT_BASE_ADDR + PGDIR_SIZE) +diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c +index fc37bbd23eb8..dad153e5a427 100644 +--- a/arch/x86/mm/dump_pagetables.c ++++ b/arch/x86/mm/dump_pagetables.c +@@ -512,11 +512,11 @@ static inline bool is_hypervisor_range(int idx) + { + #ifdef CONFIG_X86_64 + /* +- * ffff800000000000 - ffff87ffffffffff is reserved for +- * the hypervisor. ++ * A hole in the beginning of kernel address space reserved ++ * for a hypervisor. + */ +- return (idx >= pgd_index(__PAGE_OFFSET) - 16) && +- (idx < pgd_index(__PAGE_OFFSET)); ++ return (idx >= pgd_index(GUARD_HOLE_BASE_ADDR)) && ++ (idx < pgd_index(GUARD_HOLE_END_ADDR)); + #else + return false; + #endif +diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c +index a5d7ed125337..0f4fe206dcc2 100644 +--- a/arch/x86/xen/mmu_pv.c ++++ b/arch/x86/xen/mmu_pv.c +@@ -648,19 +648,20 @@ static int __xen_pgd_walk(struct mm_struct *mm, pgd_t *pgd, + unsigned long limit) + { + int i, nr, flush = 0; +- unsigned hole_low, hole_high; ++ unsigned hole_low = 0, hole_high = 0; + + /* The limit is the last byte to be touched */ + limit--; + BUG_ON(limit >= FIXADDR_TOP); + ++#ifdef CONFIG_X86_64 + /* + * 64-bit has a great big hole in the middle of the address +- * space, which contains the Xen mappings. On 32-bit these +- * will end up making a zero-sized hole and so is a no-op. ++ * space, which contains the Xen mappings. + */ +- hole_low = pgd_index(USER_LIMIT); +- hole_high = pgd_index(PAGE_OFFSET); ++ hole_low = pgd_index(GUARD_HOLE_BASE_ADDR); ++ hole_high = pgd_index(GUARD_HOLE_END_ADDR); ++#endif + + nr = pgd_index(limit) + 1; + for (i = 0; i < nr; i++) { +-- +2.19.2 + diff --git a/debian/patches/series b/debian/patches/series index 7d9fdefee..91d6c047b 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -77,6 +77,7 @@ bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch +bugfix/x86/x86-mm-Fix-guard-hole-handling.patch # Arch features features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch