Patch "x86/cpu_entry_area: Sync cpu_entry_area to initial_page_table" has been added to the 4.15-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
x86/cpu_entry_area: Sync cpu_entry_area to initial_page_table
to the 4.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
x86-cpu_entry_area-sync-cpu_entry_area-to-initial_page_table.patch
and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
945fd17ab6bab8a4d05da6c3170519fbcfe62ddbMon Sep 17 00:00:00 2001
From: Thomas Gleixner <[email protected]>
Date: Wed, 28 Feb 2018 21:14:26 +0100
Subject: x86/cpu_entry_area: Sync cpu_entry_area to initial_page_table
From: Thomas Gleixner <[email protected]>
commit 945fd17ab6bab8a4d05da6c3170519fbcfe62ddb upstream.
The separation of the cpu_entry_area from the fixmap missed the fact that on 32bit non-PAE kernels the cpu_entry_area mapping might not be covered in initial_page_table by the previous synchronizations.
This results in suspend/resume failures because 32bit utilizes initial page table for resume. The absence of the cpu_entry_area mapping results in a triple fault, aka. insta reboot.
With PAE enabled this works by chance because the PGD entry which covers the fixmap and other parts incindentally provides the cpu_entry_area mapping as well.
Synchronize the initial page table after setting up the cpu entry area. Instead of adding yet another copy of the same code, move it to a function and invoke it from the various places.
It needs to be investigated if the existing calls in setup_arch() and setup_per_cpu_areas() can be replaced by the later invocation from setup_cpu_entry_areas(), but that's beyond the scope of this fix.
--- arch/x86/include/asm/pgtable_32.h | 1 + arch/x86/include/asm/pgtable_64.h | 1 + arch/x86/kernel/setup.c | 17 +++++------------ arch/x86/kernel/setup_percpu.c | 17 ++++------------- arch/x86/mm/cpu_entry_area.c | 6 ++++++ arch/x86/mm/init_32.c | 15 +++++++++++++++ 6 files changed, 32 insertions(+), 25 deletions(-)
arch/x86/include/asm/pgtable_32.h +1 -0
@@ -32,6 +32,7 @@ extern pmd_t initial_pg_pmd[];static inline void pgtable_cache_init (void ) { }static inline void check_pgt_cache (void ) { }void paging_init (void ); +void sync_initial_page_table (void );/* * Define this if things work differently on an i386 and an i486:
arch/x86/include/asm/pgtable_64.h +1 -0
@@ -28,6 +28,7 @@ extern pgd_t init_top_pgt[];#define swapper_pg_dir init_top_pgtextern void paging_init (void ); +static inline void sync_initial_page_table (void ) { }#define pte_ERROR (e) \ pr_err("%s:%d: bad pte %p(%016lx)\n", \
arch/x86/kernel/setup.c +5 -12
@@ -1205,20 +1205,13 @@ void __init setup_arch(char **cmdline_p)kasan_init (); -#ifdef CONFIG_X86_32 -/* sync back kernel address range */ -clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -KERNEL_PGD_PTRS ); -/* -* sync back low identity map too. It is used for example -* in the 32-bit EFI stub. +* Sync back kernel address range. +* +* FIXME: Can the later sync in setup_cpu_entry_areas() replace +* this call? */ -clone_pgd_range (initial_page_table, - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); -#endif +sync_initial_page_table ();tboot_probe ();
arch/x86/kernel/setup_percpu.c +4 -13
@@ -287,24 +287,15 @@ void __init setup_per_cpu_areas(void)/* Setup cpu initialized, callin, callout masks */ setup_cpu_local_masks (); -#ifdef CONFIG_X86_32 /* * Sync back kernel address range again. We already did this in * setup_arch(), but percpu data also needs to be available in * the smpboot asm. We can't reliably pick up percpu mappings * using vmalloc_fault(), because exception dispatch needs * percpu data. +* +* FIXME: Can the later sync in setup_cpu_entry_areas() replace +* this call? */ -clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -KERNEL_PGD_PTRS ); - -/* -* sync back low identity map too. It is used for example -* in the 32-bit EFI stub. -*/ -clone_pgd_range (initial_page_table, - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); -#endif +sync_initial_page_table (); }
arch/x86/mm/cpu_entry_area.c +6 -0
@@ -163,4 +163,10 @@ void __init setup_cpu_entry_areas(void)for_each_possible_cpu (cpu)setup_cpu_entry_area (cpu); + +/* +* This is the last essential update to swapper_pgdir which needs +* to be synchronized to initial_page_table on 32bit. +*/ +sync_initial_page_table (); }
arch/x86/mm/init_32.c +15 -0
@@ -453,6 +453,21 @@ static inline void permanent_kmaps_init( }#endif /* CONFIG_HIGHMEM */ +void __init sync_initial_page_table (void ) +{ +clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , + swapper_pg_dir +KERNEL_PGD_BOUNDARY , +KERNEL_PGD_PTRS ); + +/* +* sync back low identity map too. It is used for example +* in the 32-bit EFI stub. +*/ +clone_pgd_range (initial_page_table, + swapper_pg_dir +KERNEL_PGD_BOUNDARY , +min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); +} +void __init native_pagetable_init (void ) {unsigned long pfn, va;
Patches currently in stable-queue which might be from [email protected] are
queue-4.15/x86-xen-zero-msr_ia32_spec_ctrl-before-suspend.patch queue-4.15/x86-cpu_entry_area-sync-cpu_entry_area-to-initial_page_table.patch queue-4.15/x86-platform-intel-mid-handle-intel-edison-reboot-correctly.patch queue-4.15/timers-forward-timer-base-before-migrating-timers.patch queue-4.15/hrtimer-ensure-posix-compliance-relative-clock_realtime-hrtimers.patch