]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Aug 2022 08:41:58 +0000 (10:41 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Aug 2022 08:41:58 +0000 (10:41 +0200)
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

queue-5.18/docs-kernel-parameters-update-descriptions-for-mitigations-param-with-retbleed.patch [new file with mode: 0644]
queue-5.18/edac-ghes-set-the-dimm-label-unconditionally.patch [new file with mode: 0644]
queue-5.18/edac-synopsys-re-enable-the-error-interrupts-on-v3-hw.patch [new file with mode: 0644]
queue-5.18/edac-synopsys-use-the-correct-register-to-disable-the-error-interrupt-on-v3-hw.patch [new file with mode: 0644]
queue-5.18/locking-rwsem-allow-slowpath-writer-to-ignore-handoff-bit-if-not-set-by-first-waiter.patch [new file with mode: 0644]
queue-5.18/series

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 (file)
index 0000000..6902721
--- /dev/null
@@ -0,0 +1,39 @@
+From ea304a8b89fd0d6cf94ee30cb139dc23d9f1a62f Mon Sep 17 00:00:00 2001
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Date: Thu, 28 Jul 2022 04:39:07 +0000
+Subject: docs/kernel-parameters: Update descriptions for "mitigations=" param with retbleed
+
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+
+commit ea304a8b89fd0d6cf94ee30cb139dc23d9f1a62f upstream.
+
+Updates descriptions for "mitigations=off" and "mitigations=auto,nosmt"
+with the respective retbleed= settings.
+
+Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: corbet@lwn.net
+Link: https://lore.kernel.org/r/20220728043907.165688-1-eiichi.tsukata@nutanix.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..45ad9e4
--- /dev/null
@@ -0,0 +1,108 @@
+From 5e2805d5379619c4a2e3ae4994e73b36439f4bad Mon Sep 17 00:00:00 2001
+From: Toshi Kani <toshi.kani@hpe.com>
+Date: Thu, 21 Jul 2022 12:05:03 -0600
+Subject: EDAC/ghes: Set the DIMM label unconditionally
+
+From: Toshi Kani <toshi.kani@hpe.com>
+
+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:
+    <TASK>
+    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 <rric@kernel.org>
+Signed-off-by: Robert Richter <rric@kernel.org>
+Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Tested-by: Robert Elliott <elliott@hpe.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220719220124.760359-1-toshi.kani@hpe.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..0f7a5af
--- /dev/null
@@ -0,0 +1,97 @@
+From 4bcffe941758ee17becb43af3b25487f848f6512 Mon Sep 17 00:00:00 2001
+From: Sherry Sun <sherry.sun@nxp.com>
+Date: Wed, 27 Apr 2022 09:51:37 +0800
+Subject: EDAC/synopsys: Re-enable the error interrupts on v3 hw
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+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 <sherry.sun@nxp.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Shubhrajyoti Datta <Shubhrajyoti.datta@xilinx.com>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220427015137.8406-3-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..dc48936
--- /dev/null
@@ -0,0 +1,40 @@
+From be76ceaf03bc04e74be5e28f608316b73c2b04ad Mon Sep 17 00:00:00 2001
+From: Sherry Sun <sherry.sun@nxp.com>
+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 <sherry.sun@nxp.com>
+
+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 <sherry.sun@nxp.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Shubhrajyoti Datta <Shubhrajyoti.datta@xilinx.com>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220427015137.8406-2-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..31a9b82
--- /dev/null
@@ -0,0 +1,110 @@
+From 6eebd5fb20838f5971ba17df9f55cc4f84a31053 Mon Sep 17 00:00:00 2001
+From: Waiman Long <longman@redhat.com>
+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 <longman@redhat.com>
+
+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 <longman@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: John Donnelly <john.p.donnelly@oracle.com>
+Tested-by: Mel Gorman <mgorman@techsingularity.net>
+Link: https://lore.kernel.org/r/20220622200419.778799-1-longman@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)) {
index 184070915b8aab38c4dfd9a8ee49839a58816c0c..4af338850901e92084ea73487f49d23a05bbc370 100644 (file)
@@ -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