More PCID fixes
Subsystems (3)
Andy Lutomirski
maintainercover More PCID fixes
This fixes a 32-bit boot warning, a 32-bit boot oddity that seems unsymtomatic right now, and a potential userspace corruption issue across EFI calls if PCID is enabled.
With this series applied, the only remaining issue I'm aware of is the paging-structure cache laziness problem.
I've tested SMP boot, suspend/resume, hotplug/unplug, and hibernate on a 32-bit VM, a 64-bit VM, and a 64-bit laptop. (Except hibernate on the laptop -- my laptop can't resume from hibernation on *any* kernel due to a userspace (systemd? Fedora overall integration?) issue.)
Andy Lutomirski (4):
x86/mm: Factor out CR3-building code
x86/mm/64: Stop using CR3.PCID == 0 in ASID-aware code x86/mm/32: Move setup_clear_cpu_cap(X86_FEATURE_PCID) earlier x86/mm/32: Load a sane CR3 before cpu_init() on secondary CPUs
arch/x86/include/asm/mmu_context.h | 32 ++++++++++++++++++++++++++++---- arch/x86/kernel/cpu/bugs.c | 8 -------- arch/x86/kernel/cpu/common.c | 8 ++++++++ arch/x86/kernel/smpboot.c | 13 +++++++------ arch/x86/mm/tlb.c | 11 +++++------ 5 files changed, 48 insertions(+), 24 deletions(-)
Signature · 1 line
2.13.5
Andy Lutomirski
maintainerPATCH 2/4 x86/mm/64: Stop using CR3.PCID == 0 in ASID-aware code
Putting the logical ASID into CR3's PCID bits directly means that we have two cases to consider separately: ASID == 0 and ASID != 0. This means that bugs that only hit in one of these cases trigger nondeterministically.
There were some bugs like this in the past, and I think there's still one in current kernels. In particular, we have a number of ASID-unware code paths that save CR3, write some special value, and then restore CR3. This includes suspend/resume, hibernate, kexec, EFI, and maybe other things I've missed. This is currently
dangerous: if ASID != 0, then this code sequence will leave garbage in the TLB tagged for ASID 0. We could potentially see corruption when switching back to ASID 0. In principle, an initialize_tlbstate_and_flush() call after these sequences would solve the problem, but EFI, at least, does not call this. (And it probably shouldn't -- initialize_tlbstate_and_flush() is rather expensive.)
--- arch/x86/include/asm/mmu_context.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
arch/x86/include/asm/mmu_context.h +19 -2
@@ -286,14 +286,31 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,return __pkru_allows_pkey (vma_pkey (vma), write); } +/* +* If PCID is on, ASID-aware code paths put the ASID + 1 into the PCID +* bits. This serves two purposes. It prevents a nasty situation in +* which PCID-unaware code saves CR3, loads some other value (with PCID +* == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if +* the saved ASID was nonzero. It also means that any bugs involving +* loading a PCID-enabled CR3 with CR4.PCIDE off will trigger +* deterministically. +*/ +static inline unsigned long build_cr3 (struct mm_struct *mm,u16 asid) { -return __sme_pa (mm->pgd) | asid; +if (static_cpu_has (X86_FEATURE_PCID )) { +VM_WARN_ON_ONCE (asid >4094 ); +return __sme_pa (mm->pgd) | (asid +1 ); + }else { +VM_WARN_ON_ONCE (asid !=0 ); +return __sme_pa (mm->pgd); + } }static inline unsigned long build_cr3_noflush (struct mm_struct *mm,u16 asid) { -return __sme_pa (mm->pgd) | asid |CR3_NOFLUSH ; +VM_WARN_ON_ONCE (asid >4094 ); +return __sme_pa (mm->pgd) | (asid +1 ) |CR3_NOFLUSH ; }/*
Signature · 1 line
2.13.5
Andy Lutomirski
maintainerPATCH 1/4 x86/mm: Factor out CR3-building code
In reply to Andy LutomirskiCurrent, the code that assembles a value to load into CR3 is open-coded everywhere. Factor it out into helpers build_cr3() and build_cr3_noflush().
This makes one semantic change: __get_current_cr3_fast() was wrong on SME systems. No one noticed because the only caller is in the VMX code, and there are no CPUs with both SME and VMX.
--- arch/x86/include/asm/mmu_context.h | 15 +++++++++++---- arch/x86/mm/tlb.c | 11 +++++------ 2 files changed, 16 insertions(+), 10 deletions(-)
arch/x86/include/asm/mmu_context.h +11 -4
@@ -286,6 +286,15 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,return __pkru_allows_pkey (vma_pkey (vma), write); } +static inline unsigned long build_cr3 (struct mm_struct *mm,u16 asid) +{ +return __sme_pa (mm->pgd) | asid; +} + +static inline unsigned long build_cr3_noflush (struct mm_struct *mm,u16 asid) +{ +return __sme_pa (mm->pgd) | asid |CR3_NOFLUSH ; +}/* * This can be used from process context to figure out what the value of
@@ -296,10 +305,8 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,*/ static inline unsigned long __get_current_cr3_fast (void ) { -unsigned long cr3 =__pa (this_cpu_read (cpu_tlbstate.loaded_mm)->pgd); - -if (static_cpu_has (X86_FEATURE_PCID )) - cr3 |=this_cpu_read (cpu_tlbstate.loaded_mm_asid); +unsigned long cr3 =build_cr3 (this_cpu_read (cpu_tlbstate.loaded_mm), +this_cpu_read (cpu_tlbstate.loaded_mm_asid));/* For now, be very restrictive about when this can be called. */ VM_WARN_ON (in_nmi () ||preemptible ());
arch/x86/mm/tlb.c +5 -6
@@ -126,8 +126,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,* isn't free. */ #ifdef CONFIG_DEBUG_VM -if (WARN_ON_ONCE (__read_cr3 () != - (__sme_pa (real_prev->pgd) | prev_asid))) { +if (WARN_ON_ONCE (__read_cr3 () !=build_cr3 (real_prev, prev_asid))) {/* * If we were to BUG here, we'd be very likely to kill * the system so hard that we don't see the call trace.
@@ -172,7 +171,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,*/ this_cpu_write (cpu_tlbstate.ctxs[prev_asid].tlb_gen, next_tlb_gen); -write_cr3 (__sme_pa (next->pgd) | prev_asid); +write_cr3 (build_cr3 (next, prev_asid));trace_tlb_flush (TLB_FLUSH_ON_TASK_SWITCH ,TLB_FLUSH_ALL ); }
@@ -216,12 +215,12 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,if (need_flush) {this_cpu_write (cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);this_cpu_write (cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); -write_cr3 (__sme_pa (next->pgd) | new_asid); +write_cr3 (build_cr3 (next, new_asid));trace_tlb_flush (TLB_FLUSH_ON_TASK_SWITCH ,TLB_FLUSH_ALL ); }else {/* The new ASID is already up to date. */ -write_cr3 (__sme_pa (next->pgd) | new_asid |CR3_NOFLUSH ); +write_cr3 (build_cr3_noflush (next, new_asid));trace_tlb_flush (TLB_FLUSH_ON_TASK_SWITCH ,0 ); }
@@ -265,7 +264,7 @@ void initialize_tlbstate_and_flush(void) !(cr4_read_shadow() & X86_CR4_PCIDE));/* Force ASID 0 and force a TLB flush. */ -write_cr3 (cr3 & ~CR3_PCID_MASK ); +write_cr3 (build_cr3 (mm,0 ));/* Reinitialize tlbstate. */ this_cpu_write (cpu_tlbstate.loaded_mm_asid,0 );
Signature · 1 line
2.13.5
Andy Lutomirski
maintainerPATCH 3/4 x86/mm/32: Move setup_clear_cpu_cap(X86_FEATURE_PCID) earlier
In reply to Andy LutomirskiOtherwise we might have the PCID feature bit set during cpu_init().
This is just for robustness. I haven't seen any actual bugs here.
--- arch/x86/kernel/cpu/bugs.c | 8 -------- arch/x86/kernel/cpu/common.c | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/bugs.c +0 -8
@@ -21,14 +21,6 @@void __init check_bugs (void ) { -#ifdef CONFIG_X86_32 -/* -* Regardless of whether PCID is enumerated, the SDM says -* that it can't be enabled in 32-bit mode. -*/ -setup_clear_cpu_cap (X86_FEATURE_PCID ); -#endif -identify_boot_cpu ();if (!IS_ENABLED (CONFIG_SMP )) {
arch/x86/kernel/cpu/common.c +8 -0
@@ -904,6 +904,14 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)setup_force_cpu_cap (X86_FEATURE_ALWAYS );fpu__init_system (c); + +#ifdef CONFIG_X86_32 +/* +* Regardless of whether PCID is enumerated, the SDM says +* that it can't be enabled in 32-bit mode. +*/ +setup_clear_cpu_cap (X86_FEATURE_PCID ); +#endif }void __init early_cpu_init (void )
Signature · 1 line
2.13.5
Andy Lutomirski
maintainerPATCH 4/4 x86/mm/32: Load a sane CR3 before cpu_init() on secondary CPUs
In reply to Andy LutomirskiFor unknown historical reasons (i.e. Borislav doesn't recall), 32-bit kernels invoke cpu_init() on secondary CPUs with intiial_page_table loaded into CR3. Then they set current->active_mm to &init_mm and call enter_lazy_tlb() before fixing CR3. This means that the x86 TLB code gets invoked while CR3 is inconsistent, and, with the improved PCID sanity checks I added, we warn.
Fix it by loading swapper_pg_dir (i.e. init_mm.pgd) earlier.
--- arch/x86/kernel/smpboot.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
arch/x86/kernel/smpboot.c +7 -6
@@ -232,12 +232,6 @@ static void notrace start_secondary(void *unused)*/ if (boot_cpu_has (X86_FEATURE_PCID ))__write_cr4 (__read_cr4 () |X86_CR4_PCIDE ); -cpu_init (); - x86_cpuinit.early_percpu_clock_init (); -preempt_disable (); -smp_callin (); - - enable_start_cpu0 =0 ;#ifdef CONFIG_X86_32 /* switch away from the initial page table */
@@ -245,6 +239,13 @@ static void notrace start_secondary(void *unused)__flush_tlb_all ();#endif +cpu_init (); + x86_cpuinit.early_percpu_clock_init (); +preempt_disable (); +smp_callin (); + + enable_start_cpu0 =0 ; +/* otherwise gcc will move up smp_processor_id before the cpu_init */ barrier ();/*
Signature · 1 line
2.13.5
tip-bot for Andy Lutomirski
merge bot[tip:x86/urgent] x86/mm: Factor out CR3-building code
In reply to Andy Lutomirskix86/mm: Factor out CR3-building code
Commit-ID: 47061a24e2ee5bd8a40d473d47a5bd823fa0081f Gitweb: http://git.kernel.org/tip/47061a24e2ee5bd8a40d473d47a5bd823fa0081f Author: Andy Lutomirski <[email protected]> AuthorDate: Sun, 17 Sep 2017 09:03:48 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 17 Sep 2017 18:59:08 +0200
x86/mm: Factor out CR3-building code
Current, the code that assembles a value to load into CR3 is open-coded everywhere. Factor it out into helpers build_cr3() and build_cr3_noflush().
This makes one semantic change: __get_current_cr3_fast() was wrong on SME systems. No one noticed because the only caller is in the VMX code, and there are no CPUs with both SME and VMX.
--- arch/x86/include/asm/mmu_context.h | 15 +++++++++++---- arch/x86/mm/tlb.c | 11 +++++------ 2 files changed, 16 insertions(+), 10 deletions(-)
arch/x86/include/asm/mmu_context.h +11 -4
@@ -286,6 +286,15 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,return __pkru_allows_pkey (vma_pkey (vma), write); } +static inline unsigned long build_cr3 (struct mm_struct *mm,u16 asid) +{ +return __sme_pa (mm->pgd) | asid; +} + +static inline unsigned long build_cr3_noflush (struct mm_struct *mm,u16 asid) +{ +return __sme_pa (mm->pgd) | asid |CR3_NOFLUSH ; +}/* * This can be used from process context to figure out what the value of
@@ -296,10 +305,8 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,*/ static inline unsigned long __get_current_cr3_fast (void ) { -unsigned long cr3 =__pa (this_cpu_read (cpu_tlbstate.loaded_mm)->pgd); - -if (static_cpu_has (X86_FEATURE_PCID )) - cr3 |=this_cpu_read (cpu_tlbstate.loaded_mm_asid); +unsigned long cr3 =build_cr3 (this_cpu_read (cpu_tlbstate.loaded_mm), +this_cpu_read (cpu_tlbstate.loaded_mm_asid));/* For now, be very restrictive about when this can be called. */ VM_WARN_ON (in_nmi () ||preemptible ());
arch/x86/mm/tlb.c +5 -6
@@ -126,8 +126,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,* isn't free. */ #ifdef CONFIG_DEBUG_VM -if (WARN_ON_ONCE (__read_cr3 () != - (__sme_pa (real_prev->pgd) | prev_asid))) { +if (WARN_ON_ONCE (__read_cr3 () !=build_cr3 (real_prev, prev_asid))) {/* * If we were to BUG here, we'd be very likely to kill * the system so hard that we don't see the call trace.
@@ -172,7 +171,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,*/ this_cpu_write (cpu_tlbstate.ctxs[prev_asid].tlb_gen, next_tlb_gen); -write_cr3 (__sme_pa (next->pgd) | prev_asid); +write_cr3 (build_cr3 (next, prev_asid));trace_tlb_flush (TLB_FLUSH_ON_TASK_SWITCH ,TLB_FLUSH_ALL ); }
@@ -216,12 +215,12 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,if (need_flush) {this_cpu_write (cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);this_cpu_write (cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); -write_cr3 (__sme_pa (next->pgd) | new_asid); +write_cr3 (build_cr3 (next, new_asid));trace_tlb_flush (TLB_FLUSH_ON_TASK_SWITCH ,TLB_FLUSH_ALL ); }else {/* The new ASID is already up to date. */ -write_cr3 (__sme_pa (next->pgd) | new_asid |CR3_NOFLUSH ); +write_cr3 (build_cr3_noflush (next, new_asid));trace_tlb_flush (TLB_FLUSH_ON_TASK_SWITCH ,0 ); }
@@ -265,7 +264,7 @@ void initialize_tlbstate_and_flush(void) !(cr4_read_shadow() & X86_CR4_PCIDE));/* Force ASID 0 and force a TLB flush. */ -write_cr3 (cr3 & ~CR3_PCID_MASK ); +write_cr3 (build_cr3 (mm,0 ));/* Reinitialize tlbstate. */ this_cpu_write (cpu_tlbstate.loaded_mm_asid,0 );
tip-bot for Andy Lutomirski
merge bot[tip:x86/urgent] x86/mm/64: Stop using CR3.PCID == 0 in ASID-aware code
In reply to Andy Lutomirskix86/mm/64: Stop using CR3.PCID == 0 in ASID-aware code
Commit-ID: 52a2af400c1075219b3f0ce5c96fc961da44018a Gitweb: http://git.kernel.org/tip/52a2af400c1075219b3f0ce5c96fc961da44018a Author: Andy Lutomirski <[email protected]> AuthorDate: Sun, 17 Sep 2017 09:03:49 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 17 Sep 2017 18:59:08 +0200
x86/mm/64: Stop using CR3.PCID == 0 in ASID-aware code
Putting the logical ASID into CR3's PCID bits directly means that we have two cases to consider separately: ASID == 0 and ASID != 0. This means that bugs that only hit in one of these cases trigger nondeterministically.
There were some bugs like this in the past, and I think there's still one in current kernels. In particular, we have a number of ASID-unware code paths that save CR3, write some special value, and then restore CR3. This includes suspend/resume, hibernate, kexec, EFI, and maybe other things I've missed. This is currently
dangerous: if ASID != 0, then this code sequence will leave garbage in the TLB tagged for ASID 0. We could potentially see corruption when switching back to ASID 0. In principle, an initialize_tlbstate_and_flush() call after these sequences would solve the problem, but EFI, at least, does not call this. (And it probably shouldn't -- initialize_tlbstate_and_flush() is rather expensive.)
--- arch/x86/include/asm/mmu_context.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
arch/x86/include/asm/mmu_context.h +19 -2
@@ -286,14 +286,31 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,return __pkru_allows_pkey (vma_pkey (vma), write); } +/* +* If PCID is on, ASID-aware code paths put the ASID+1 into the PCID +* bits. This serves two purposes. It prevents a nasty situation in +* which PCID-unaware code saves CR3, loads some other value (with PCID +* == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if +* the saved ASID was nonzero. It also means that any bugs involving +* loading a PCID-enabled CR3 with CR4.PCIDE off will trigger +* deterministically. +*/ +static inline unsigned long build_cr3 (struct mm_struct *mm,u16 asid) { -return __sme_pa (mm->pgd) | asid; +if (static_cpu_has (X86_FEATURE_PCID )) { +VM_WARN_ON_ONCE (asid >4094 ); +return __sme_pa (mm->pgd) | (asid +1 ); + }else { +VM_WARN_ON_ONCE (asid !=0 ); +return __sme_pa (mm->pgd); + } }static inline unsigned long build_cr3_noflush (struct mm_struct *mm,u16 asid) { -return __sme_pa (mm->pgd) | asid |CR3_NOFLUSH ; +VM_WARN_ON_ONCE (asid >4094 ); +return __sme_pa (mm->pgd) | (asid +1 ) |CR3_NOFLUSH ; }/*
tip-bot for Andy Lutomirski
merge bot[tip:x86/urgent] x86/mm/32: Move setup_clear_cpu_cap(X86_FEATURE_PCID) earlier
In reply to Andy Lutomirskix86/mm/32: Move setup_clear_cpu_cap(X86_FEATURE_PCID) earlier
Commit-ID: b8b7abaed7a49b350f8ba659ddc264b04931d581 Gitweb: http://git.kernel.org/tip/b8b7abaed7a49b350f8ba659ddc264b04931d581 Author: Andy Lutomirski <[email protected]> AuthorDate: Sun, 17 Sep 2017 09:03:50 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 17 Sep 2017 18:59:08 +0200
x86/mm/32: Move setup_clear_cpu_cap(X86_FEATURE_PCID) earlier
Otherwise we might have the PCID feature bit set during cpu_init().
This is just for robustness. I haven't seen any actual bugs here.
--- arch/x86/kernel/cpu/bugs.c | 8 -------- arch/x86/kernel/cpu/common.c | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/bugs.c +0 -8
@@ -21,14 +21,6 @@void __init check_bugs (void ) { -#ifdef CONFIG_X86_32 -/* -* Regardless of whether PCID is enumerated, the SDM says -* that it can't be enabled in 32-bit mode. -*/ -setup_clear_cpu_cap (X86_FEATURE_PCID ); -#endif -identify_boot_cpu ();if (!IS_ENABLED (CONFIG_SMP )) {
arch/x86/kernel/cpu/common.c +8 -0
@@ -904,6 +904,14 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)setup_force_cpu_cap (X86_FEATURE_ALWAYS );fpu__init_system (c); + +#ifdef CONFIG_X86_32 +/* +* Regardless of whether PCID is enumerated, the SDM says +* that it can't be enabled in 32-bit mode. +*/ +setup_clear_cpu_cap (X86_FEATURE_PCID ); +#endif }void __init early_cpu_init (void )
tip-bot for Andy Lutomirski
merge bot[tip:x86/urgent] x86/mm/32: Load a sane CR3 before cpu_init() on secondary CPUs
In reply to Andy Lutomirskix86/mm/32: Load a sane CR3 before cpu_init() on secondary CPUs
Commit-ID: 4ba55e65f471d011d3ba2ac2022180ea0877d68e Gitweb: http://git.kernel.org/tip/4ba55e65f471d011d3ba2ac2022180ea0877d68e Author: Andy Lutomirski <[email protected]> AuthorDate: Sun, 17 Sep 2017 09:03:51 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 17 Sep 2017 18:59:09 +0200
x86/mm/32: Load a sane CR3 before cpu_init() on secondary CPUs
For unknown historical reasons (i.e. Borislav doesn't recall), 32-bit kernels invoke cpu_init() on secondary CPUs with initial_page_table loaded into CR3. Then they set current->active_mm to &init_mm and call enter_lazy_tlb() before fixing CR3. This means that the x86 TLB code gets invoked while CR3 is inconsistent, and, with the improved PCID sanity checks I added, we warn.
Fix it by loading swapper_pg_dir (i.e. init_mm.pgd) earlier.
--- arch/x86/kernel/smpboot.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
arch/x86/kernel/smpboot.c +7 -6
@@ -232,12 +232,6 @@ static void notrace start_secondary(void *unused)*/ if (boot_cpu_has (X86_FEATURE_PCID ))__write_cr4 (__read_cr4 () |X86_CR4_PCIDE ); -cpu_init (); - x86_cpuinit.early_percpu_clock_init (); -preempt_disable (); -smp_callin (); - - enable_start_cpu0 =0 ;#ifdef CONFIG_X86_32 /* switch away from the initial page table */
@@ -245,6 +239,13 @@ static void notrace start_secondary(void *unused)__flush_tlb_all ();#endif +cpu_init (); + x86_cpuinit.early_percpu_clock_init (); +preempt_disable (); +smp_callin (); + + enable_start_cpu0 =0 ; +/* otherwise gcc will move up smp_processor_id before the cpu_init */ barrier ();/*
Paul Menzel
Tested-byRe: [tip:x86/urgent] x86/mm/32: Load a sane CR3 before cpu_init() on secondary CPUs
Dear Andy,
Quoted 7 lines · tip-bot for Andy Lutomirski
Commit-ID: 4ba55e65f471d011d3ba2ac2022180ea0877d68e Gitweb: http://git.kernel.org/tip/4ba55e65f471d011d3ba2ac2022180ea0877d68e Author: Andy Lutomirski <[email protected]> AuthorDate: Sun, 17 Sep 2017 09:03:51 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 17 Sep 2017 18:59:09 +0200
Quoted 7 lines
x86/mm/32: Load a sane CR3 before
cpu_init()on secondary CPUsFor unknown historical reasons (i.e. Borislav doesn't recall), 32-bit kernels invoke
cpu_init()on secondary CPUs withinitial_page_tableloaded into CR3. Then they setcurrent->active_mmto&init_mmand callenter_lazy_tlb()before fixing CR3.
If this should be changed, I’d be happy to help.
Quoted 6 lines
This means that the x86 TLB code gets invoked while CR3 is inconsistent, and, with the improved PCID sanity checks I added, we warn.
Fix it by loading
swapper_pg_dir(i.e. init_mm.pgd) earlier.
Quoted 10 lines
Reported-by Paul Menzel <[email protected]>Reported-by Pavel Machek <[email protected]>Signed-off-by Andy Lutomirski <[email protected]>Cc Borislav Petkov <[email protected]>Cc Borislav Petkov <[email protected]>Cc Linus Torvalds <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Thomas Gleixner <[email protected]>Fixes 72c0098d92ce ("x86/mm: Reinitialize TLB state on hotplug and resume")
This should use the HTTPS protocol.
Quoted 4 lines
Signed-off-by Ingo Molnar <[email protected]>--- arch/x86/kernel/smpboot.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
[…]
Thank you for the fix.
Kind regards,
Paul
Pavel Machek
Tested-byRe: [tip:x86/urgent] x86/mm/32: Load a sane CR3 before cpu_init() on secondary CPUs
In reply to tip-bot for Andy LutomirskiQuoted 17 lines · tip-bot for Andy Lutomirski
Commit-ID: 4ba55e65f471d011d3ba2ac2022180ea0877d68e Gitweb: http://git.kernel.org/tip/4ba55e65f471d011d3ba2ac2022180ea0877d68e Author: Andy Lutomirski <[email protected]> AuthorDate: Sun, 17 Sep 2017 09:03:51 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 17 Sep 2017 18:59:09 +0200x86/mm/32: Load a sane CR3 before
cpu_init()on secondary CPUsFor unknown historical reasons (i.e. Borislav doesn't recall), 32-bit kernels invoke
cpu_init()on secondary CPUs withinitial_page_tableloaded into CR3. Then they setcurrent->active_mmto&init_mmand callenter_lazy_tlb()before fixing CR3. This means that the x86 TLB code gets invoked while CR3 is inconsistent, and, with the improved PCID sanity checks I added, we warn.
Quoted 4 lines
Fix it by loading
swapper_pg_dir(i.e. init_mm.pgd) earlier.Reported-by Paul Menzel <[email protected]>Reported-by Pavel Machek <[email protected]>
4.14.0-rc1-next-20170919 does not produce the warning during bootup.
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html