From 1e6b9d2b677cf7b3a7759eda203d9c1adff9c35e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 Jun 2023 21:41:03 +0200 Subject: [PATCH] drop broken x86 patch from a bunch of queues --- queue-4.14/series | 1 - ...e-kexec-vs.-mwait_play_dead-breakage.patch | 182 ------------------ queue-4.19/series | 1 - ...e-kexec-vs.-mwait_play_dead-breakage.patch | 182 ------------------ queue-5.10/series | 1 - ...e-kexec-vs.-mwait_play_dead-breakage.patch | 179 ----------------- queue-5.15/series | 1 - ...e-kexec-vs.-mwait_play_dead-breakage.patch | 179 ----------------- queue-5.4/series | 1 - ...e-kexec-vs.-mwait_play_dead-breakage.patch | 182 ------------------ 10 files changed, 909 deletions(-) delete mode 100644 queue-4.14/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch delete mode 100644 queue-4.19/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch delete mode 100644 queue-5.10/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch delete mode 100644 queue-5.15/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch delete mode 100644 queue-5.4/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch diff --git a/queue-4.14/series b/queue-4.14/series index 7d4ec1e9440..967f63b28ea 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -1,4 +1,3 @@ gfs2-don-t-deref-jdesc-in-evict.patch x86-microcode-amd-load-late-on-both-threads-too.patch x86-smp-use-dedicated-cache-line-for-mwait_play_dead.patch -x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch diff --git a/queue-4.14/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch b/queue-4.14/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch deleted file mode 100644 index 80ef9cb6f7c..00000000000 --- a/queue-4.14/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch +++ /dev/null @@ -1,182 +0,0 @@ -From d7893093a7417527c0d73c9832244e65c9d0114f Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 15 Jun 2023 22:33:57 +0200 -Subject: x86/smp: Cure kexec() vs. mwait_play_dead() breakage - -From: Thomas Gleixner - -commit d7893093a7417527c0d73c9832244e65c9d0114f upstream. - -TLDR: It's a mess. - -When kexec() is executed on a system with offline CPUs, which are parked in -mwait_play_dead() it can end up in a triple fault during the bootup of the -kexec kernel or cause hard to diagnose data corruption. - -The reason is that kexec() eventually overwrites the previous kernel's text, -page tables, data and stack. If it writes to the cache line which is -monitored by a previously offlined CPU, MWAIT resumes execution and ends -up executing the wrong text, dereferencing overwritten page tables or -corrupting the kexec kernels data. - -Cure this by bringing the offlined CPUs out of MWAIT into HLT. - -Write to the monitored cache line of each offline CPU, which makes MWAIT -resume execution. The written control word tells the offlined CPUs to issue -HLT, which does not have the MWAIT problem. - -That does not help, if a stray NMI, MCE or SMI hits the offlined CPUs as -those make it come out of HLT. - -A follow up change will put them into INIT, which protects at least against -NMI and SMI. - -Fixes: ea53069231f9 ("x86, hotplug: Use mwait to offline a processor, fix the legacy case") -Reported-by: Ashok Raj -Signed-off-by: Thomas Gleixner -Tested-by: Ashok Raj -Reviewed-by: Ashok Raj -Cc: stable@vger.kernel.org -Link: https://lore.kernel.org/r/20230615193330.492257119@linutronix.de -Signed-off-by: Greg Kroah-Hartman ---- - arch/x86/include/asm/smp.h | 2 + - arch/x86/kernel/smp.c | 5 +++ - arch/x86/kernel/smpboot.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 66 insertions(+) - ---- a/arch/x86/include/asm/smp.h -+++ b/arch/x86/include/asm/smp.h -@@ -141,6 +141,8 @@ void play_dead_common(void); - void wbinvd_on_cpu(int cpu); - int wbinvd_on_all_cpus(void); - -+void smp_kick_mwait_play_dead(void); -+ - void native_send_call_func_ipi(const struct cpumask *mask); - void native_send_call_func_single_ipi(int cpu); - void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); ---- a/arch/x86/kernel/smp.c -+++ b/arch/x86/kernel/smp.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -200,6 +201,10 @@ static void native_stop_other_cpus(int w - * does lots of things not suitable in a panic situation. - */ - -+ /* For kexec, ensure that offline CPUs are out of MWAIT and in HLT */ -+ if (kexec_in_progress) -+ smp_kick_mwait_play_dead(); -+ - /* - * We start by using the REBOOT_VECTOR irq. - * The irq is treated as a sync point to allow critical ---- a/arch/x86/kernel/smpboot.c -+++ b/arch/x86/kernel/smpboot.c -@@ -56,6 +56,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -99,6 +100,9 @@ struct mwait_cpu_dead { - unsigned int status; - }; - -+#define CPUDEAD_MWAIT_WAIT 0xDEADBEEF -+#define CPUDEAD_MWAIT_KEXEC_HLT 0x4A17DEAD -+ - /* - * Cache line aligned data for mwait_play_dead(). Separate on purpose so - * that it's unlikely to be touched by other CPUs. -@@ -163,6 +167,10 @@ static void smp_callin(void) - { - int cpuid, phys_id; - -+ /* Mop up eventual mwait_play_dead() wreckage */ -+ this_cpu_write(mwait_cpu_dead.status, 0); -+ this_cpu_write(mwait_cpu_dead.control, 0); -+ - /* - * If waken up by an INIT in an 82489DX configuration - * cpu_callout_mask guarantees we don't get here before -@@ -1685,6 +1693,10 @@ static inline void mwait_play_dead(void) - (highest_subcstate - 1); - } - -+ /* Set up state for the kexec() hack below */ -+ md->status = CPUDEAD_MWAIT_WAIT; -+ md->control = CPUDEAD_MWAIT_WAIT; -+ - wbinvd(); - - while (1) { -@@ -1701,6 +1713,24 @@ static inline void mwait_play_dead(void) - __monitor(md, 0, 0); - mb(); - __mwait(eax, 0); -+ -+ if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) { -+ /* -+ * Kexec is about to happen. Don't go back into mwait() as -+ * the kexec kernel might overwrite text and data including -+ * page tables and stack. So mwait() would resume when the -+ * monitor cache line is written to and then the CPU goes -+ * south due to overwritten text, page tables and stack. -+ * -+ * Note: This does _NOT_ protect against a stray MCE, NMI, -+ * SMI. They will resume execution at the instruction -+ * following the HLT instruction and run into the problem -+ * which this is trying to prevent. -+ */ -+ WRITE_ONCE(md->status, CPUDEAD_MWAIT_KEXEC_HLT); -+ while(1) -+ native_halt(); -+ } - /* - * If NMI wants to wake up CPU0, start CPU0. - */ -@@ -1709,6 +1739,35 @@ static inline void mwait_play_dead(void) - } - } - -+/* -+ * Kick all "offline" CPUs out of mwait on kexec(). See comment in -+ * mwait_play_dead(). -+ */ -+void smp_kick_mwait_play_dead(void) -+{ -+ u32 newstate = CPUDEAD_MWAIT_KEXEC_HLT; -+ struct mwait_cpu_dead *md; -+ unsigned int cpu, i; -+ -+ for_each_cpu_andnot(cpu, cpu_present_mask, cpu_online_mask) { -+ md = per_cpu_ptr(&mwait_cpu_dead, cpu); -+ -+ /* Does it sit in mwait_play_dead() ? */ -+ if (READ_ONCE(md->status) != CPUDEAD_MWAIT_WAIT) -+ continue; -+ -+ /* Wait up to 5ms */ -+ for (i = 0; READ_ONCE(md->status) != newstate && i < 1000; i++) { -+ /* Bring it out of mwait */ -+ WRITE_ONCE(md->control, newstate); -+ udelay(5); -+ } -+ -+ if (READ_ONCE(md->status) != newstate) -+ pr_err_once("CPU%u is stuck in mwait_play_dead()\n", cpu); -+ } -+} -+ - void hlt_play_dead(void) - { - if (__this_cpu_read(cpu_info.x86) >= 4) diff --git a/queue-4.19/series b/queue-4.19/series index 7d4ec1e9440..967f63b28ea 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -1,4 +1,3 @@ gfs2-don-t-deref-jdesc-in-evict.patch x86-microcode-amd-load-late-on-both-threads-too.patch x86-smp-use-dedicated-cache-line-for-mwait_play_dead.patch -x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch diff --git a/queue-4.19/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch b/queue-4.19/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch deleted file mode 100644 index 44f17b89a5f..00000000000 --- a/queue-4.19/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch +++ /dev/null @@ -1,182 +0,0 @@ -From d7893093a7417527c0d73c9832244e65c9d0114f Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 15 Jun 2023 22:33:57 +0200 -Subject: x86/smp: Cure kexec() vs. mwait_play_dead() breakage - -From: Thomas Gleixner - -commit d7893093a7417527c0d73c9832244e65c9d0114f upstream. - -TLDR: It's a mess. - -When kexec() is executed on a system with offline CPUs, which are parked in -mwait_play_dead() it can end up in a triple fault during the bootup of the -kexec kernel or cause hard to diagnose data corruption. - -The reason is that kexec() eventually overwrites the previous kernel's text, -page tables, data and stack. If it writes to the cache line which is -monitored by a previously offlined CPU, MWAIT resumes execution and ends -up executing the wrong text, dereferencing overwritten page tables or -corrupting the kexec kernels data. - -Cure this by bringing the offlined CPUs out of MWAIT into HLT. - -Write to the monitored cache line of each offline CPU, which makes MWAIT -resume execution. The written control word tells the offlined CPUs to issue -HLT, which does not have the MWAIT problem. - -That does not help, if a stray NMI, MCE or SMI hits the offlined CPUs as -those make it come out of HLT. - -A follow up change will put them into INIT, which protects at least against -NMI and SMI. - -Fixes: ea53069231f9 ("x86, hotplug: Use mwait to offline a processor, fix the legacy case") -Reported-by: Ashok Raj -Signed-off-by: Thomas Gleixner -Tested-by: Ashok Raj -Reviewed-by: Ashok Raj -Cc: stable@vger.kernel.org -Link: https://lore.kernel.org/r/20230615193330.492257119@linutronix.de -Signed-off-by: Greg Kroah-Hartman ---- - arch/x86/include/asm/smp.h | 2 + - arch/x86/kernel/smp.c | 5 +++ - arch/x86/kernel/smpboot.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 66 insertions(+) - ---- a/arch/x86/include/asm/smp.h -+++ b/arch/x86/include/asm/smp.h -@@ -142,6 +142,8 @@ void play_dead_common(void); - void wbinvd_on_cpu(int cpu); - int wbinvd_on_all_cpus(void); - -+void smp_kick_mwait_play_dead(void); -+ - void native_send_call_func_ipi(const struct cpumask *mask); - void native_send_call_func_single_ipi(int cpu); - void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); ---- a/arch/x86/kernel/smp.c -+++ b/arch/x86/kernel/smp.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -200,6 +201,10 @@ static void native_stop_other_cpus(int w - * does lots of things not suitable in a panic situation. - */ - -+ /* For kexec, ensure that offline CPUs are out of MWAIT and in HLT */ -+ if (kexec_in_progress) -+ smp_kick_mwait_play_dead(); -+ - /* - * We start by using the REBOOT_VECTOR irq. - * The irq is treated as a sync point to allow critical ---- a/arch/x86/kernel/smpboot.c -+++ b/arch/x86/kernel/smpboot.c -@@ -56,6 +56,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -101,6 +102,9 @@ struct mwait_cpu_dead { - unsigned int status; - }; - -+#define CPUDEAD_MWAIT_WAIT 0xDEADBEEF -+#define CPUDEAD_MWAIT_KEXEC_HLT 0x4A17DEAD -+ - /* - * Cache line aligned data for mwait_play_dead(). Separate on purpose so - * that it's unlikely to be touched by other CPUs. -@@ -162,6 +166,10 @@ static void smp_callin(void) - { - int cpuid, phys_id; - -+ /* Mop up eventual mwait_play_dead() wreckage */ -+ this_cpu_write(mwait_cpu_dead.status, 0); -+ this_cpu_write(mwait_cpu_dead.control, 0); -+ - /* - * If waken up by an INIT in an 82489DX configuration - * cpu_callout_mask guarantees we don't get here before -@@ -1642,6 +1650,10 @@ static inline void mwait_play_dead(void) - (highest_subcstate - 1); - } - -+ /* Set up state for the kexec() hack below */ -+ md->status = CPUDEAD_MWAIT_WAIT; -+ md->control = CPUDEAD_MWAIT_WAIT; -+ - wbinvd(); - - while (1) { -@@ -1658,6 +1670,24 @@ static inline void mwait_play_dead(void) - __monitor(md, 0, 0); - mb(); - __mwait(eax, 0); -+ -+ if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) { -+ /* -+ * Kexec is about to happen. Don't go back into mwait() as -+ * the kexec kernel might overwrite text and data including -+ * page tables and stack. So mwait() would resume when the -+ * monitor cache line is written to and then the CPU goes -+ * south due to overwritten text, page tables and stack. -+ * -+ * Note: This does _NOT_ protect against a stray MCE, NMI, -+ * SMI. They will resume execution at the instruction -+ * following the HLT instruction and run into the problem -+ * which this is trying to prevent. -+ */ -+ WRITE_ONCE(md->status, CPUDEAD_MWAIT_KEXEC_HLT); -+ while(1) -+ native_halt(); -+ } - /* - * If NMI wants to wake up CPU0, start CPU0. - */ -@@ -1666,6 +1696,35 @@ static inline void mwait_play_dead(void) - } - } - -+/* -+ * Kick all "offline" CPUs out of mwait on kexec(). See comment in -+ * mwait_play_dead(). -+ */ -+void smp_kick_mwait_play_dead(void) -+{ -+ u32 newstate = CPUDEAD_MWAIT_KEXEC_HLT; -+ struct mwait_cpu_dead *md; -+ unsigned int cpu, i; -+ -+ for_each_cpu_andnot(cpu, cpu_present_mask, cpu_online_mask) { -+ md = per_cpu_ptr(&mwait_cpu_dead, cpu); -+ -+ /* Does it sit in mwait_play_dead() ? */ -+ if (READ_ONCE(md->status) != CPUDEAD_MWAIT_WAIT) -+ continue; -+ -+ /* Wait up to 5ms */ -+ for (i = 0; READ_ONCE(md->status) != newstate && i < 1000; i++) { -+ /* Bring it out of mwait */ -+ WRITE_ONCE(md->control, newstate); -+ udelay(5); -+ } -+ -+ if (READ_ONCE(md->status) != newstate) -+ pr_err_once("CPU%u is stuck in mwait_play_dead()\n", cpu); -+ } -+} -+ - void hlt_play_dead(void) - { - if (__this_cpu_read(cpu_info.x86) >= 4) diff --git a/queue-5.10/series b/queue-5.10/series index 5e958573fb5..a4e21be9183 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -1,4 +1,3 @@ media-atomisp-fix-variable-dereferenced-before-check-asd.patch x86-microcode-amd-load-late-on-both-threads-too.patch x86-smp-use-dedicated-cache-line-for-mwait_play_dead.patch -x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch diff --git a/queue-5.10/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch b/queue-5.10/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch deleted file mode 100644 index 12274c20ea1..00000000000 --- a/queue-5.10/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch +++ /dev/null @@ -1,179 +0,0 @@ -From d7893093a7417527c0d73c9832244e65c9d0114f Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 15 Jun 2023 22:33:57 +0200 -Subject: x86/smp: Cure kexec() vs. mwait_play_dead() breakage - -From: Thomas Gleixner - -commit d7893093a7417527c0d73c9832244e65c9d0114f upstream. - -TLDR: It's a mess. - -When kexec() is executed on a system with offline CPUs, which are parked in -mwait_play_dead() it can end up in a triple fault during the bootup of the -kexec kernel or cause hard to diagnose data corruption. - -The reason is that kexec() eventually overwrites the previous kernel's text, -page tables, data and stack. If it writes to the cache line which is -monitored by a previously offlined CPU, MWAIT resumes execution and ends -up executing the wrong text, dereferencing overwritten page tables or -corrupting the kexec kernels data. - -Cure this by bringing the offlined CPUs out of MWAIT into HLT. - -Write to the monitored cache line of each offline CPU, which makes MWAIT -resume execution. The written control word tells the offlined CPUs to issue -HLT, which does not have the MWAIT problem. - -That does not help, if a stray NMI, MCE or SMI hits the offlined CPUs as -those make it come out of HLT. - -A follow up change will put them into INIT, which protects at least against -NMI and SMI. - -Fixes: ea53069231f9 ("x86, hotplug: Use mwait to offline a processor, fix the legacy case") -Reported-by: Ashok Raj -Signed-off-by: Thomas Gleixner -Tested-by: Ashok Raj -Reviewed-by: Ashok Raj -Cc: stable@vger.kernel.org -Link: https://lore.kernel.org/r/20230615193330.492257119@linutronix.de -Signed-off-by: Greg Kroah-Hartman ---- - arch/x86/include/asm/smp.h | 2 + - arch/x86/kernel/smp.c | 5 +++ - arch/x86/kernel/smpboot.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 66 insertions(+) - ---- a/arch/x86/include/asm/smp.h -+++ b/arch/x86/include/asm/smp.h -@@ -134,6 +134,8 @@ void wbinvd_on_cpu(int cpu); - int wbinvd_on_all_cpus(void); - void cond_wakeup_cpu0(void); - -+void smp_kick_mwait_play_dead(void); -+ - void native_smp_send_reschedule(int cpu); - void native_send_call_func_ipi(const struct cpumask *mask); - void native_send_call_func_single_ipi(int cpu); ---- a/arch/x86/kernel/smp.c -+++ b/arch/x86/kernel/smp.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -157,6 +158,10 @@ static void native_stop_other_cpus(int w - * does lots of things not suitable in a panic situation. - */ - -+ /* For kexec, ensure that offline CPUs are out of MWAIT and in HLT */ -+ if (kexec_in_progress) -+ smp_kick_mwait_play_dead(); -+ - /* - * We start by using the REBOOT_VECTOR irq. - * The irq is treated as a sync point to allow critical ---- a/arch/x86/kernel/smpboot.c -+++ b/arch/x86/kernel/smpboot.c -@@ -53,6 +53,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -105,6 +106,9 @@ struct mwait_cpu_dead { - unsigned int status; - }; - -+#define CPUDEAD_MWAIT_WAIT 0xDEADBEEF -+#define CPUDEAD_MWAIT_KEXEC_HLT 0x4A17DEAD -+ - /* - * Cache line aligned data for mwait_play_dead(). Separate on purpose so - * that it's unlikely to be touched by other CPUs. -@@ -169,6 +173,10 @@ static void smp_callin(void) - { - int cpuid; - -+ /* Mop up eventual mwait_play_dead() wreckage */ -+ this_cpu_write(mwait_cpu_dead.status, 0); -+ this_cpu_write(mwait_cpu_dead.control, 0); -+ - /* - * If waken up by an INIT in an 82489DX configuration - * cpu_callout_mask guarantees we don't get here before -@@ -1723,6 +1731,10 @@ static inline void mwait_play_dead(void) - (highest_subcstate - 1); - } - -+ /* Set up state for the kexec() hack below */ -+ md->status = CPUDEAD_MWAIT_WAIT; -+ md->control = CPUDEAD_MWAIT_WAIT; -+ - wbinvd(); - - while (1) { -@@ -1740,10 +1752,57 @@ static inline void mwait_play_dead(void) - mb(); - __mwait(eax, 0); - -+ if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) { -+ /* -+ * Kexec is about to happen. Don't go back into mwait() as -+ * the kexec kernel might overwrite text and data including -+ * page tables and stack. So mwait() would resume when the -+ * monitor cache line is written to and then the CPU goes -+ * south due to overwritten text, page tables and stack. -+ * -+ * Note: This does _NOT_ protect against a stray MCE, NMI, -+ * SMI. They will resume execution at the instruction -+ * following the HLT instruction and run into the problem -+ * which this is trying to prevent. -+ */ -+ WRITE_ONCE(md->status, CPUDEAD_MWAIT_KEXEC_HLT); -+ while(1) -+ native_halt(); -+ } -+ - cond_wakeup_cpu0(); - } - } - -+/* -+ * Kick all "offline" CPUs out of mwait on kexec(). See comment in -+ * mwait_play_dead(). -+ */ -+void smp_kick_mwait_play_dead(void) -+{ -+ u32 newstate = CPUDEAD_MWAIT_KEXEC_HLT; -+ struct mwait_cpu_dead *md; -+ unsigned int cpu, i; -+ -+ for_each_cpu_andnot(cpu, cpu_present_mask, cpu_online_mask) { -+ md = per_cpu_ptr(&mwait_cpu_dead, cpu); -+ -+ /* Does it sit in mwait_play_dead() ? */ -+ if (READ_ONCE(md->status) != CPUDEAD_MWAIT_WAIT) -+ continue; -+ -+ /* Wait up to 5ms */ -+ for (i = 0; READ_ONCE(md->status) != newstate && i < 1000; i++) { -+ /* Bring it out of mwait */ -+ WRITE_ONCE(md->control, newstate); -+ udelay(5); -+ } -+ -+ if (READ_ONCE(md->status) != newstate) -+ pr_err_once("CPU%u is stuck in mwait_play_dead()\n", cpu); -+ } -+} -+ - void hlt_play_dead(void) - { - if (__this_cpu_read(cpu_info.x86) >= 4) diff --git a/queue-5.15/series b/queue-5.15/series index ae0f1341a52..01e9e6d8f41 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -5,4 +5,3 @@ mm-hwpoison-when-copy-on-write-hits-poison-take-page-offline.patch drm-amdgpu-set-vmbo-destroy-after-pt-bo-is-created.patch x86-microcode-amd-load-late-on-both-threads-too.patch x86-smp-use-dedicated-cache-line-for-mwait_play_dead.patch -x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch diff --git a/queue-5.15/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch b/queue-5.15/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch deleted file mode 100644 index 83171697ad5..00000000000 --- a/queue-5.15/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch +++ /dev/null @@ -1,179 +0,0 @@ -From d7893093a7417527c0d73c9832244e65c9d0114f Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 15 Jun 2023 22:33:57 +0200 -Subject: x86/smp: Cure kexec() vs. mwait_play_dead() breakage - -From: Thomas Gleixner - -commit d7893093a7417527c0d73c9832244e65c9d0114f upstream. - -TLDR: It's a mess. - -When kexec() is executed on a system with offline CPUs, which are parked in -mwait_play_dead() it can end up in a triple fault during the bootup of the -kexec kernel or cause hard to diagnose data corruption. - -The reason is that kexec() eventually overwrites the previous kernel's text, -page tables, data and stack. If it writes to the cache line which is -monitored by a previously offlined CPU, MWAIT resumes execution and ends -up executing the wrong text, dereferencing overwritten page tables or -corrupting the kexec kernels data. - -Cure this by bringing the offlined CPUs out of MWAIT into HLT. - -Write to the monitored cache line of each offline CPU, which makes MWAIT -resume execution. The written control word tells the offlined CPUs to issue -HLT, which does not have the MWAIT problem. - -That does not help, if a stray NMI, MCE or SMI hits the offlined CPUs as -those make it come out of HLT. - -A follow up change will put them into INIT, which protects at least against -NMI and SMI. - -Fixes: ea53069231f9 ("x86, hotplug: Use mwait to offline a processor, fix the legacy case") -Reported-by: Ashok Raj -Signed-off-by: Thomas Gleixner -Tested-by: Ashok Raj -Reviewed-by: Ashok Raj -Cc: stable@vger.kernel.org -Link: https://lore.kernel.org/r/20230615193330.492257119@linutronix.de -Signed-off-by: Greg Kroah-Hartman ---- - arch/x86/include/asm/smp.h | 2 + - arch/x86/kernel/smp.c | 5 +++ - arch/x86/kernel/smpboot.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 66 insertions(+) - ---- a/arch/x86/include/asm/smp.h -+++ b/arch/x86/include/asm/smp.h -@@ -134,6 +134,8 @@ void wbinvd_on_cpu(int cpu); - int wbinvd_on_all_cpus(void); - void cond_wakeup_cpu0(void); - -+void smp_kick_mwait_play_dead(void); -+ - void native_smp_send_reschedule(int cpu); - void native_send_call_func_ipi(const struct cpumask *mask); - void native_send_call_func_single_ipi(int cpu); ---- a/arch/x86/kernel/smp.c -+++ b/arch/x86/kernel/smp.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -157,6 +158,10 @@ static void native_stop_other_cpus(int w - * does lots of things not suitable in a panic situation. - */ - -+ /* For kexec, ensure that offline CPUs are out of MWAIT and in HLT */ -+ if (kexec_in_progress) -+ smp_kick_mwait_play_dead(); -+ - /* - * We start by using the REBOOT_VECTOR irq. - * The irq is treated as a sync point to allow critical ---- a/arch/x86/kernel/smpboot.c -+++ b/arch/x86/kernel/smpboot.c -@@ -53,6 +53,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -110,6 +111,9 @@ struct mwait_cpu_dead { - unsigned int status; - }; - -+#define CPUDEAD_MWAIT_WAIT 0xDEADBEEF -+#define CPUDEAD_MWAIT_KEXEC_HLT 0x4A17DEAD -+ - /* - * Cache line aligned data for mwait_play_dead(). Separate on purpose so - * that it's unlikely to be touched by other CPUs. -@@ -174,6 +178,10 @@ static void smp_callin(void) - { - int cpuid; - -+ /* Mop up eventual mwait_play_dead() wreckage */ -+ this_cpu_write(mwait_cpu_dead.status, 0); -+ this_cpu_write(mwait_cpu_dead.control, 0); -+ - /* - * If waken up by an INIT in an 82489DX configuration - * cpu_callout_mask guarantees we don't get here before -@@ -1734,6 +1742,10 @@ static inline void mwait_play_dead(void) - (highest_subcstate - 1); - } - -+ /* Set up state for the kexec() hack below */ -+ md->status = CPUDEAD_MWAIT_WAIT; -+ md->control = CPUDEAD_MWAIT_WAIT; -+ - wbinvd(); - - while (1) { -@@ -1751,10 +1763,57 @@ static inline void mwait_play_dead(void) - mb(); - __mwait(eax, 0); - -+ if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) { -+ /* -+ * Kexec is about to happen. Don't go back into mwait() as -+ * the kexec kernel might overwrite text and data including -+ * page tables and stack. So mwait() would resume when the -+ * monitor cache line is written to and then the CPU goes -+ * south due to overwritten text, page tables and stack. -+ * -+ * Note: This does _NOT_ protect against a stray MCE, NMI, -+ * SMI. They will resume execution at the instruction -+ * following the HLT instruction and run into the problem -+ * which this is trying to prevent. -+ */ -+ WRITE_ONCE(md->status, CPUDEAD_MWAIT_KEXEC_HLT); -+ while(1) -+ native_halt(); -+ } -+ - cond_wakeup_cpu0(); - } - } - -+/* -+ * Kick all "offline" CPUs out of mwait on kexec(). See comment in -+ * mwait_play_dead(). -+ */ -+void smp_kick_mwait_play_dead(void) -+{ -+ u32 newstate = CPUDEAD_MWAIT_KEXEC_HLT; -+ struct mwait_cpu_dead *md; -+ unsigned int cpu, i; -+ -+ for_each_cpu_andnot(cpu, cpu_present_mask, cpu_online_mask) { -+ md = per_cpu_ptr(&mwait_cpu_dead, cpu); -+ -+ /* Does it sit in mwait_play_dead() ? */ -+ if (READ_ONCE(md->status) != CPUDEAD_MWAIT_WAIT) -+ continue; -+ -+ /* Wait up to 5ms */ -+ for (i = 0; READ_ONCE(md->status) != newstate && i < 1000; i++) { -+ /* Bring it out of mwait */ -+ WRITE_ONCE(md->control, newstate); -+ udelay(5); -+ } -+ -+ if (READ_ONCE(md->status) != newstate) -+ pr_err_once("CPU%u is stuck in mwait_play_dead()\n", cpu); -+ } -+} -+ - void hlt_play_dead(void) - { - if (__this_cpu_read(cpu_info.x86) >= 4) diff --git a/queue-5.4/series b/queue-5.4/series index 7d4ec1e9440..967f63b28ea 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -1,4 +1,3 @@ gfs2-don-t-deref-jdesc-in-evict.patch x86-microcode-amd-load-late-on-both-threads-too.patch x86-smp-use-dedicated-cache-line-for-mwait_play_dead.patch -x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch diff --git a/queue-5.4/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch b/queue-5.4/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch deleted file mode 100644 index dfcfdf051fa..00000000000 --- a/queue-5.4/x86-smp-cure-kexec-vs.-mwait_play_dead-breakage.patch +++ /dev/null @@ -1,182 +0,0 @@ -From d7893093a7417527c0d73c9832244e65c9d0114f Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 15 Jun 2023 22:33:57 +0200 -Subject: x86/smp: Cure kexec() vs. mwait_play_dead() breakage - -From: Thomas Gleixner - -commit d7893093a7417527c0d73c9832244e65c9d0114f upstream. - -TLDR: It's a mess. - -When kexec() is executed on a system with offline CPUs, which are parked in -mwait_play_dead() it can end up in a triple fault during the bootup of the -kexec kernel or cause hard to diagnose data corruption. - -The reason is that kexec() eventually overwrites the previous kernel's text, -page tables, data and stack. If it writes to the cache line which is -monitored by a previously offlined CPU, MWAIT resumes execution and ends -up executing the wrong text, dereferencing overwritten page tables or -corrupting the kexec kernels data. - -Cure this by bringing the offlined CPUs out of MWAIT into HLT. - -Write to the monitored cache line of each offline CPU, which makes MWAIT -resume execution. The written control word tells the offlined CPUs to issue -HLT, which does not have the MWAIT problem. - -That does not help, if a stray NMI, MCE or SMI hits the offlined CPUs as -those make it come out of HLT. - -A follow up change will put them into INIT, which protects at least against -NMI and SMI. - -Fixes: ea53069231f9 ("x86, hotplug: Use mwait to offline a processor, fix the legacy case") -Reported-by: Ashok Raj -Signed-off-by: Thomas Gleixner -Tested-by: Ashok Raj -Reviewed-by: Ashok Raj -Cc: stable@vger.kernel.org -Link: https://lore.kernel.org/r/20230615193330.492257119@linutronix.de -Signed-off-by: Greg Kroah-Hartman ---- - arch/x86/include/asm/smp.h | 2 + - arch/x86/kernel/smp.c | 5 +++ - arch/x86/kernel/smpboot.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 66 insertions(+) - ---- a/arch/x86/include/asm/smp.h -+++ b/arch/x86/include/asm/smp.h -@@ -143,6 +143,8 @@ void play_dead_common(void); - void wbinvd_on_cpu(int cpu); - int wbinvd_on_all_cpus(void); - -+void smp_kick_mwait_play_dead(void); -+ - void native_smp_send_reschedule(int cpu); - void native_send_call_func_ipi(const struct cpumask *mask); - void native_send_call_func_single_ipi(int cpu); ---- a/arch/x86/kernel/smp.c -+++ b/arch/x86/kernel/smp.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -158,6 +159,10 @@ static void native_stop_other_cpus(int w - * does lots of things not suitable in a panic situation. - */ - -+ /* For kexec, ensure that offline CPUs are out of MWAIT and in HLT */ -+ if (kexec_in_progress) -+ smp_kick_mwait_play_dead(); -+ - /* - * We start by using the REBOOT_VECTOR irq. - * The irq is treated as a sync point to allow critical ---- a/arch/x86/kernel/smpboot.c -+++ b/arch/x86/kernel/smpboot.c -@@ -54,6 +54,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -104,6 +105,9 @@ struct mwait_cpu_dead { - unsigned int status; - }; - -+#define CPUDEAD_MWAIT_WAIT 0xDEADBEEF -+#define CPUDEAD_MWAIT_KEXEC_HLT 0x4A17DEAD -+ - /* - * Cache line aligned data for mwait_play_dead(). Separate on purpose so - * that it's unlikely to be touched by other CPUs. -@@ -166,6 +170,10 @@ static void smp_callin(void) - { - int cpuid; - -+ /* Mop up eventual mwait_play_dead() wreckage */ -+ this_cpu_write(mwait_cpu_dead.status, 0); -+ this_cpu_write(mwait_cpu_dead.control, 0); -+ - /* - * If waken up by an INIT in an 82489DX configuration - * cpu_callout_mask guarantees we don't get here before -@@ -1724,6 +1732,10 @@ static inline void mwait_play_dead(void) - (highest_subcstate - 1); - } - -+ /* Set up state for the kexec() hack below */ -+ md->status = CPUDEAD_MWAIT_WAIT; -+ md->control = CPUDEAD_MWAIT_WAIT; -+ - wbinvd(); - - while (1) { -@@ -1740,6 +1752,24 @@ static inline void mwait_play_dead(void) - __monitor(md, 0, 0); - mb(); - __mwait(eax, 0); -+ -+ if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) { -+ /* -+ * Kexec is about to happen. Don't go back into mwait() as -+ * the kexec kernel might overwrite text and data including -+ * page tables and stack. So mwait() would resume when the -+ * monitor cache line is written to and then the CPU goes -+ * south due to overwritten text, page tables and stack. -+ * -+ * Note: This does _NOT_ protect against a stray MCE, NMI, -+ * SMI. They will resume execution at the instruction -+ * following the HLT instruction and run into the problem -+ * which this is trying to prevent. -+ */ -+ WRITE_ONCE(md->status, CPUDEAD_MWAIT_KEXEC_HLT); -+ while(1) -+ native_halt(); -+ } - /* - * If NMI wants to wake up CPU0, start CPU0. - */ -@@ -1748,6 +1778,35 @@ static inline void mwait_play_dead(void) - } - } - -+/* -+ * Kick all "offline" CPUs out of mwait on kexec(). See comment in -+ * mwait_play_dead(). -+ */ -+void smp_kick_mwait_play_dead(void) -+{ -+ u32 newstate = CPUDEAD_MWAIT_KEXEC_HLT; -+ struct mwait_cpu_dead *md; -+ unsigned int cpu, i; -+ -+ for_each_cpu_andnot(cpu, cpu_present_mask, cpu_online_mask) { -+ md = per_cpu_ptr(&mwait_cpu_dead, cpu); -+ -+ /* Does it sit in mwait_play_dead() ? */ -+ if (READ_ONCE(md->status) != CPUDEAD_MWAIT_WAIT) -+ continue; -+ -+ /* Wait up to 5ms */ -+ for (i = 0; READ_ONCE(md->status) != newstate && i < 1000; i++) { -+ /* Bring it out of mwait */ -+ WRITE_ONCE(md->control, newstate); -+ udelay(5); -+ } -+ -+ if (READ_ONCE(md->status) != newstate) -+ pr_err_once("CPU%u is stuck in mwait_play_dead()\n", cpu); -+ } -+} -+ - void hlt_play_dead(void) - { - if (__this_cpu_read(cpu_info.x86) >= 4) -- 2.47.3