From 126b77aa74a63b5a11101c8367ebf4007b352900 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 1 Aug 2022 10:41:58 +0200 Subject: [PATCH] 5.18-stable patches added patches: docs-kernel-parameters-update-descriptions-for-mitigations-param-with-retbleed.patch edac-ghes-set-the-dimm-label-unconditionally.patch edac-synopsys-re-enable-the-error-interrupts-on-v3-hw.patch edac-synopsys-use-the-correct-register-to-disable-the-error-interrupt-on-v3-hw.patch locking-rwsem-allow-slowpath-writer-to-ignore-handoff-bit-if-not-set-by-first-waiter.patch --- ...-for-mitigations-param-with-retbleed.patch | 39 +++++++ ...s-set-the-dimm-label-unconditionally.patch | 108 +++++++++++++++++ ...enable-the-error-interrupts-on-v3-hw.patch | 97 +++++++++++++++ ...disable-the-error-interrupt-on-v3-hw.patch | 40 +++++++ ...ndoff-bit-if-not-set-by-first-waiter.patch | 110 ++++++++++++++++++ queue-5.18/series | 5 + 6 files changed, 399 insertions(+) create mode 100644 queue-5.18/docs-kernel-parameters-update-descriptions-for-mitigations-param-with-retbleed.patch create mode 100644 queue-5.18/edac-ghes-set-the-dimm-label-unconditionally.patch create mode 100644 queue-5.18/edac-synopsys-re-enable-the-error-interrupts-on-v3-hw.patch create mode 100644 queue-5.18/edac-synopsys-use-the-correct-register-to-disable-the-error-interrupt-on-v3-hw.patch create mode 100644 queue-5.18/locking-rwsem-allow-slowpath-writer-to-ignore-handoff-bit-if-not-set-by-first-waiter.patch diff --git a/queue-5.18/docs-kernel-parameters-update-descriptions-for-mitigations-param-with-retbleed.patch b/queue-5.18/docs-kernel-parameters-update-descriptions-for-mitigations-param-with-retbleed.patch new file mode 100644 index 00000000000..6902721163c --- /dev/null +++ b/queue-5.18/docs-kernel-parameters-update-descriptions-for-mitigations-param-with-retbleed.patch @@ -0,0 +1,39 @@ +From ea304a8b89fd0d6cf94ee30cb139dc23d9f1a62f Mon Sep 17 00:00:00 2001 +From: Eiichi Tsukata +Date: Thu, 28 Jul 2022 04:39:07 +0000 +Subject: docs/kernel-parameters: Update descriptions for "mitigations=" param with retbleed + +From: Eiichi Tsukata + +commit ea304a8b89fd0d6cf94ee30cb139dc23d9f1a62f upstream. + +Updates descriptions for "mitigations=off" and "mitigations=auto,nosmt" +with the respective retbleed= settings. + +Signed-off-by: Eiichi Tsukata +Signed-off-by: Borislav Petkov +Cc: corbet@lwn.net +Link: https://lore.kernel.org/r/20220728043907.165688-1-eiichi.tsukata@nutanix.com +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/admin-guide/kernel-parameters.txt | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -3106,6 +3106,7 @@ + no_entry_flush [PPC] + no_uaccess_flush [PPC] + mmio_stale_data=off [X86] ++ retbleed=off [X86] + + Exceptions: + This does not have any effect on +@@ -3128,6 +3129,7 @@ + mds=full,nosmt [X86] + tsx_async_abort=full,nosmt [X86] + mmio_stale_data=full,nosmt [X86] ++ retbleed=auto,nosmt [X86] + + mminit_loglevel= + [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this diff --git a/queue-5.18/edac-ghes-set-the-dimm-label-unconditionally.patch b/queue-5.18/edac-ghes-set-the-dimm-label-unconditionally.patch new file mode 100644 index 00000000000..45ad9e43fc3 --- /dev/null +++ b/queue-5.18/edac-ghes-set-the-dimm-label-unconditionally.patch @@ -0,0 +1,108 @@ +From 5e2805d5379619c4a2e3ae4994e73b36439f4bad Mon Sep 17 00:00:00 2001 +From: Toshi Kani +Date: Thu, 21 Jul 2022 12:05:03 -0600 +Subject: EDAC/ghes: Set the DIMM label unconditionally + +From: Toshi Kani + +commit 5e2805d5379619c4a2e3ae4994e73b36439f4bad upstream. + +The commit + + cb51a371d08e ("EDAC/ghes: Setup DIMM label from DMI and use it in error reports") + +enforced that both the bank and device strings passed to +dimm_setup_label() are not NULL. + +However, there are BIOSes, for example on a + + HPE ProLiant DL360 Gen10/ProLiant DL360 Gen10, BIOS U32 03/15/2019 + +which don't populate both strings: + + Handle 0x0020, DMI type 17, 84 bytes + Memory Device + Array Handle: 0x0013 + Error Information Handle: Not Provided + Total Width: 72 bits + Data Width: 64 bits + Size: 32 GB + Form Factor: DIMM + Set: None + Locator: PROC 1 DIMM 1 <===== device + Bank Locator: Not Specified <===== bank + +This results in a buffer overflow because ghes_edac_register() calls +strlen() on an uninitialized label, which had non-zero values left over +from krealloc_array(): + + detected buffer overflow in __fortify_strlen + ------------[ cut here ]------------ + kernel BUG at lib/string_helpers.c:983! + invalid opcode: 0000 [#1] PREEMPT SMP NOPTI + CPU: 1 PID: 1 Comm: swapper/0 Tainted: G I 5.18.6-200.fc36.x86_64 #1 + Hardware name: HPE ProLiant DL360 Gen10/ProLiant DL360 Gen10, BIOS U32 03/15/2019 + RIP: 0010:fortify_panic + ... + Call Trace: + + ghes_edac_register.cold + ghes_probe + platform_probe + really_probe + __driver_probe_device + driver_probe_device + __driver_attach + ? __device_attach_driver + bus_for_each_dev + bus_add_driver + driver_register + acpi_ghes_init + acpi_init + ? acpi_sleep_proc_init + do_one_initcall + +The label contains garbage because the commit in Fixes reallocs the +DIMMs array while scanning the system but doesn't clear the newly +allocated memory. + +Change dimm_setup_label() to always initialize the label to fix the +issue. Set it to the empty string in case BIOS does not provide both +bank and device so that ghes_edac_register() can keep the default label +given by edac_mc_alloc_dimms(). + + [ bp: Rewrite commit message. ] + +Fixes: b9cae27728d1f ("EDAC/ghes: Scan the system once on driver init") +Co-developed-by: Robert Richter +Signed-off-by: Robert Richter +Signed-off-by: Toshi Kani +Signed-off-by: Borislav Petkov +Tested-by: Robert Elliott +Cc: +Link: https://lore.kernel.org/r/20220719220124.760359-1-toshi.kani@hpe.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/edac/ghes_edac.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/edac/ghes_edac.c ++++ b/drivers/edac/ghes_edac.c +@@ -101,9 +101,14 @@ static void dimm_setup_label(struct dimm + + dmi_memdev_name(handle, &bank, &device); + +- /* both strings must be non-zero */ +- if (bank && *bank && device && *device) +- snprintf(dimm->label, sizeof(dimm->label), "%s %s", bank, device); ++ /* ++ * Set to a NULL string when both bank and device are zero. In this case, ++ * the label assigned by default will be preserved. ++ */ ++ snprintf(dimm->label, sizeof(dimm->label), "%s%s%s", ++ (bank && *bank) ? bank : "", ++ (bank && *bank && device && *device) ? " " : "", ++ (device && *device) ? device : ""); + } + + static void assign_dmi_dimm_info(struct dimm_info *dimm, struct memdev_dmi_entry *entry) diff --git a/queue-5.18/edac-synopsys-re-enable-the-error-interrupts-on-v3-hw.patch b/queue-5.18/edac-synopsys-re-enable-the-error-interrupts-on-v3-hw.patch new file mode 100644 index 00000000000..0f7a5af6660 --- /dev/null +++ b/queue-5.18/edac-synopsys-re-enable-the-error-interrupts-on-v3-hw.patch @@ -0,0 +1,97 @@ +From 4bcffe941758ee17becb43af3b25487f848f6512 Mon Sep 17 00:00:00 2001 +From: Sherry Sun +Date: Wed, 27 Apr 2022 09:51:37 +0800 +Subject: EDAC/synopsys: Re-enable the error interrupts on v3 hw + +From: Sherry Sun + +commit 4bcffe941758ee17becb43af3b25487f848f6512 upstream. + +zynqmp_get_error_info() writes 0 to the ECC_CLR_OFST register after +an interrupt for a {un-,}correctable error is raised, which disables +the error interrupts. Then the interrupt handler will be called only +once. Therefore, re-enable the error interrupt line at the end of +intr_handler() for v3.x Synopsys EDAC DDR. + +Fixes: f7824ded4149 ("EDAC/synopsys: Add support for version 3 of the Synopsys EDAC DDR") +Signed-off-by: Sherry Sun +Signed-off-by: Borislav Petkov +Reviewed-by: Shubhrajyoti Datta +Acked-by: Michal Simek +Cc: +Link: https://lore.kernel.org/r/20220427015137.8406-3-sherry.sun@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/edac/synopsys_edac.c | 47 ++++++++++++++++++++++--------------------- + 1 file changed, 25 insertions(+), 22 deletions(-) + +--- a/drivers/edac/synopsys_edac.c ++++ b/drivers/edac/synopsys_edac.c +@@ -527,6 +527,28 @@ static void handle_error(struct mem_ctl_ + memset(p, 0, sizeof(*p)); + } + ++static void enable_intr(struct synps_edac_priv *priv) ++{ ++ /* Enable UE/CE Interrupts */ ++ if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR) ++ writel(DDR_UE_MASK | DDR_CE_MASK, ++ priv->baseaddr + ECC_CLR_OFST); ++ else ++ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK, ++ priv->baseaddr + DDR_QOS_IRQ_EN_OFST); ++ ++} ++ ++static void disable_intr(struct synps_edac_priv *priv) ++{ ++ /* Disable UE/CE Interrupts */ ++ if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR) ++ writel(0x0, priv->baseaddr + ECC_CLR_OFST); ++ else ++ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK, ++ priv->baseaddr + DDR_QOS_IRQ_DB_OFST); ++} ++ + /** + * intr_handler - Interrupt Handler for ECC interrupts. + * @irq: IRQ number. +@@ -568,6 +590,9 @@ static irqreturn_t intr_handler(int irq, + /* v3.0 of the controller does not have this register */ + if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) + writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST); ++ else ++ enable_intr(priv); ++ + return IRQ_HANDLED; + } + +@@ -850,28 +875,6 @@ static void mc_init(struct mem_ctl_info + init_csrows(mci); + } + +-static void enable_intr(struct synps_edac_priv *priv) +-{ +- /* Enable UE/CE Interrupts */ +- if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR) +- writel(DDR_UE_MASK | DDR_CE_MASK, +- priv->baseaddr + ECC_CLR_OFST); +- else +- writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK, +- priv->baseaddr + DDR_QOS_IRQ_EN_OFST); +- +-} +- +-static void disable_intr(struct synps_edac_priv *priv) +-{ +- /* Disable UE/CE Interrupts */ +- if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR) +- writel(0x0, priv->baseaddr + ECC_CLR_OFST); +- else +- writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK, +- priv->baseaddr + DDR_QOS_IRQ_DB_OFST); +-} +- + static int setup_irq(struct mem_ctl_info *mci, + struct platform_device *pdev) + { diff --git a/queue-5.18/edac-synopsys-use-the-correct-register-to-disable-the-error-interrupt-on-v3-hw.patch b/queue-5.18/edac-synopsys-use-the-correct-register-to-disable-the-error-interrupt-on-v3-hw.patch new file mode 100644 index 00000000000..dc48936bf2e --- /dev/null +++ b/queue-5.18/edac-synopsys-use-the-correct-register-to-disable-the-error-interrupt-on-v3-hw.patch @@ -0,0 +1,40 @@ +From be76ceaf03bc04e74be5e28f608316b73c2b04ad Mon Sep 17 00:00:00 2001 +From: Sherry Sun +Date: Wed, 27 Apr 2022 09:51:36 +0800 +Subject: EDAC/synopsys: Use the correct register to disable the error interrupt on v3 hw + +From: Sherry Sun + +commit be76ceaf03bc04e74be5e28f608316b73c2b04ad upstream. + +v3.x Synopsys EDAC DDR doesn't have the QOS Interrupt register. Use the +ECC Clear Register to disable the error interrupts instead. + +Fixes: f7824ded4149 ("EDAC/synopsys: Add support for version 3 of the Synopsys EDAC DDR") +Signed-off-by: Sherry Sun +Signed-off-by: Borislav Petkov +Reviewed-by: Shubhrajyoti Datta +Acked-by: Michal Simek +Cc: +Link: https://lore.kernel.org/r/20220427015137.8406-2-sherry.sun@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/edac/synopsys_edac.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/edac/synopsys_edac.c ++++ b/drivers/edac/synopsys_edac.c +@@ -865,8 +865,11 @@ static void enable_intr(struct synps_eda + static void disable_intr(struct synps_edac_priv *priv) + { + /* Disable UE/CE Interrupts */ +- writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK, +- priv->baseaddr + DDR_QOS_IRQ_DB_OFST); ++ if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR) ++ writel(0x0, priv->baseaddr + ECC_CLR_OFST); ++ else ++ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK, ++ priv->baseaddr + DDR_QOS_IRQ_DB_OFST); + } + + static int setup_irq(struct mem_ctl_info *mci, diff --git a/queue-5.18/locking-rwsem-allow-slowpath-writer-to-ignore-handoff-bit-if-not-set-by-first-waiter.patch b/queue-5.18/locking-rwsem-allow-slowpath-writer-to-ignore-handoff-bit-if-not-set-by-first-waiter.patch new file mode 100644 index 00000000000..31a9b8233b4 --- /dev/null +++ b/queue-5.18/locking-rwsem-allow-slowpath-writer-to-ignore-handoff-bit-if-not-set-by-first-waiter.patch @@ -0,0 +1,110 @@ +From 6eebd5fb20838f5971ba17df9f55cc4f84a31053 Mon Sep 17 00:00:00 2001 +From: Waiman Long +Date: Wed, 22 Jun 2022 16:04:19 -0400 +Subject: locking/rwsem: Allow slowpath writer to ignore handoff bit if not set by first waiter + +From: Waiman Long + +commit 6eebd5fb20838f5971ba17df9f55cc4f84a31053 upstream. + +With commit d257cc8cb8d5 ("locking/rwsem: Make handoff bit handling more +consistent"), the writer that sets the handoff bit can be interrupted +out without clearing the bit if the wait queue isn't empty. This disables +reader and writer optimistic lock spinning and stealing. + +Now if a non-first writer in the queue is somehow woken up or a new +waiter enters the slowpath, it can't acquire the lock. This is not the +case before commit d257cc8cb8d5 as the writer that set the handoff bit +will clear it when exiting out via the out_nolock path. This is less +efficient as the busy rwsem stays in an unlock state for a longer time. + +In some cases, this new behavior may cause lockups as shown in [1] and +[2]. + +This patch allows a non-first writer to ignore the handoff bit if it +is not originally set or initiated by the first waiter. This patch is +shown to be effective in fixing the lockup problem reported in [1]. + +[1] https://lore.kernel.org/lkml/20220617134325.GC30825@techsingularity.net/ +[2] https://lore.kernel.org/lkml/3f02975c-1a9d-be20-32cf-f1d8e3dfafcc@oracle.com/ + +Fixes: d257cc8cb8d5 ("locking/rwsem: Make handoff bit handling more consistent") +Signed-off-by: Waiman Long +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: John Donnelly +Tested-by: Mel Gorman +Link: https://lore.kernel.org/r/20220622200419.778799-1-longman@redhat.com +Signed-off-by: Greg Kroah-Hartman +--- + kernel/locking/rwsem.c | 30 ++++++++++++++++++++---------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +--- a/kernel/locking/rwsem.c ++++ b/kernel/locking/rwsem.c +@@ -334,8 +334,6 @@ struct rwsem_waiter { + struct task_struct *task; + enum rwsem_waiter_type type; + unsigned long timeout; +- +- /* Writer only, not initialized in reader */ + bool handoff_set; + }; + #define rwsem_first_waiter(sem) \ +@@ -455,10 +453,12 @@ static void rwsem_mark_wake(struct rw_se + * to give up the lock), request a HANDOFF to + * force the issue. + */ +- if (!(oldcount & RWSEM_FLAG_HANDOFF) && +- time_after(jiffies, waiter->timeout)) { +- adjustment -= RWSEM_FLAG_HANDOFF; +- lockevent_inc(rwsem_rlock_handoff); ++ if (time_after(jiffies, waiter->timeout)) { ++ if (!(oldcount & RWSEM_FLAG_HANDOFF)) { ++ adjustment -= RWSEM_FLAG_HANDOFF; ++ lockevent_inc(rwsem_rlock_handoff); ++ } ++ waiter->handoff_set = true; + } + + atomic_long_add(-adjustment, &sem->count); +@@ -568,7 +568,7 @@ static void rwsem_mark_wake(struct rw_se + static inline bool rwsem_try_write_lock(struct rw_semaphore *sem, + struct rwsem_waiter *waiter) + { +- bool first = rwsem_first_waiter(sem) == waiter; ++ struct rwsem_waiter *first = rwsem_first_waiter(sem); + long count, new; + + lockdep_assert_held(&sem->wait_lock); +@@ -578,11 +578,20 @@ static inline bool rwsem_try_write_lock( + bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF); + + if (has_handoff) { +- if (!first) ++ /* ++ * Honor handoff bit and yield only when the first ++ * waiter is the one that set it. Otherwisee, we ++ * still try to acquire the rwsem. ++ */ ++ if (first->handoff_set && (waiter != first)) + return false; + +- /* First waiter inherits a previously set handoff bit */ +- waiter->handoff_set = true; ++ /* ++ * First waiter can inherit a previously set handoff ++ * bit and spin on rwsem if lock acquisition fails. ++ */ ++ if (waiter == first) ++ waiter->handoff_set = true; + } + + new = count; +@@ -972,6 +981,7 @@ queue: + waiter.task = current; + waiter.type = RWSEM_WAITING_FOR_READ; + waiter.timeout = jiffies + RWSEM_WAIT_TIMEOUT; ++ waiter.handoff_set = false; + + raw_spin_lock_irq(&sem->wait_lock); + if (list_empty(&sem->wait_list)) { diff --git a/queue-5.18/series b/queue-5.18/series index 184070915b8..4af33885090 100644 --- a/queue-5.18/series +++ b/queue-5.18/series @@ -80,3 +80,8 @@ mm-hmm-fault-non-owner-device-private-entries.patch page_alloc-fix-invalid-watermark-check-on-a-negative-value.patch tcp-fix-data-races-around-sysctl_tcp_workaround_sign.patch arm-9216-1-fix-max_dma_address-overflow.patch +edac-ghes-set-the-dimm-label-unconditionally.patch +edac-synopsys-use-the-correct-register-to-disable-the-error-interrupt-on-v3-hw.patch +edac-synopsys-re-enable-the-error-interrupts-on-v3-hw.patch +docs-kernel-parameters-update-descriptions-for-mitigations-param-with-retbleed.patch +locking-rwsem-allow-slowpath-writer-to-ignore-handoff-bit-if-not-set-by-first-waiter.patch -- 2.47.3