--- /dev/null
+From 31643d84b8c3d9c846aa0e20bc033e46c68c7e7d Mon Sep 17 00:00:00 2001
+From: Carlos Llamas <cmllamas@google.com>
+Date: Thu, 11 Jul 2024 20:14:51 +0000
+Subject: binder: fix hang of unregistered readers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Carlos Llamas <cmllamas@google.com>
+
+commit 31643d84b8c3d9c846aa0e20bc033e46c68c7e7d upstream.
+
+With the introduction of binder_available_for_proc_work_ilocked() in
+commit 1b77e9dcc3da ("ANDROID: binder: remove proc waitqueue") a binder
+thread can only "wait_for_proc_work" after its thread->looper has been
+marked as BINDER_LOOPER_STATE_{ENTERED|REGISTERED}.
+
+This means an unregistered reader risks waiting indefinitely for work
+since it never gets added to the proc->waiting_threads. If there are no
+further references to its waitqueue either the task will hang. The same
+applies to readers using the (e)poll interface.
+
+I couldn't find the rationale behind this restriction. So this patch
+restores the previous behavior of allowing unregistered threads to
+"wait_for_proc_work". Note that an error message for this scenario,
+which had previously become unreachable, is now re-enabled.
+
+Fixes: 1b77e9dcc3da ("ANDROID: binder: remove proc waitqueue")
+Cc: stable@vger.kernel.org
+Cc: Martijn Coenen <maco@google.com>
+Cc: Arve Hjønnevåg <arve@google.com>
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Link: https://lore.kernel.org/r/20240711201452.2017543-1-cmllamas@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/android/binder.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -542,9 +542,7 @@ static bool binder_has_work(struct binde
+ static bool binder_available_for_proc_work_ilocked(struct binder_thread *thread)
+ {
+ return !thread->transaction_stack &&
+- binder_worklist_empty_ilocked(&thread->todo) &&
+- (thread->looper & (BINDER_LOOPER_STATE_ENTERED |
+- BINDER_LOOPER_STATE_REGISTERED));
++ binder_worklist_empty_ilocked(&thread->todo);
+ }
+
+ static void binder_wakeup_poll_threads_ilocked(struct binder_proc *proc,
--- /dev/null
+From ab11dac93d2d568d151b1918d7b84c2d02bacbd5 Mon Sep 17 00:00:00 2001
+From: tuhaowen <tuhaowen@uniontech.com>
+Date: Mon, 8 Jul 2024 16:04:30 +0800
+Subject: dev/parport: fix the array out-of-bounds risk
+
+From: tuhaowen <tuhaowen@uniontech.com>
+
+commit ab11dac93d2d568d151b1918d7b84c2d02bacbd5 upstream.
+
+Fixed array out-of-bounds issues caused by sprintf
+by replacing it with snprintf for safer data copying,
+ensuring the destination buffer is not overflowed.
+
+Below is the stack trace I encountered during the actual issue:
+
+[ 66.575408s] [pid:5118,cpu4,QThread,4]Kernel panic - not syncing: stack-protector:
+Kernel stack is corrupted in: do_hardware_base_addr+0xcc/0xd0 [parport]
+[ 66.575408s] [pid:5118,cpu4,QThread,5]CPU: 4 PID: 5118 Comm:
+QThread Tainted: G S W O 5.10.97-arm64-desktop #7100.57021.2
+[ 66.575439s] [pid:5118,cpu4,QThread,6]TGID: 5087 Comm: EFileApp
+[ 66.575439s] [pid:5118,cpu4,QThread,7]Hardware name: HUAWEI HUAWEI QingYun
+PGUX-W515x-B081/SP1PANGUXM, BIOS 1.00.07 04/29/2024
+[ 66.575439s] [pid:5118,cpu4,QThread,8]Call trace:
+[ 66.575469s] [pid:5118,cpu4,QThread,9] dump_backtrace+0x0/0x1c0
+[ 66.575469s] [pid:5118,cpu4,QThread,0] show_stack+0x14/0x20
+[ 66.575469s] [pid:5118,cpu4,QThread,1] dump_stack+0xd4/0x10c
+[ 66.575500s] [pid:5118,cpu4,QThread,2] panic+0x1d8/0x3bc
+[ 66.575500s] [pid:5118,cpu4,QThread,3] __stack_chk_fail+0x2c/0x38
+[ 66.575500s] [pid:5118,cpu4,QThread,4] do_hardware_base_addr+0xcc/0xd0 [parport]
+
+Signed-off-by: tuhaowen <tuhaowen@uniontech.com>
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/20240708080430.8221-1-tuhaowen@uniontech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/parport/procfs.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/parport/procfs.c
++++ b/drivers/parport/procfs.c
+@@ -51,12 +51,12 @@ static int do_active_device(struct ctl_t
+
+ for (dev = port->devices; dev ; dev = dev->next) {
+ if(dev == port->cad) {
+- len += sprintf(buffer, "%s\n", dev->name);
++ len += snprintf(buffer, sizeof(buffer), "%s\n", dev->name);
+ }
+ }
+
+ if(!len) {
+- len += sprintf(buffer, "%s\n", "none");
++ len += snprintf(buffer, sizeof(buffer), "%s\n", "none");
+ }
+
+ if (len > *lenp)
+@@ -87,19 +87,19 @@ static int do_autoprobe(struct ctl_table
+ }
+
+ if ((str = info->class_name) != NULL)
+- len += sprintf (buffer + len, "CLASS:%s;\n", str);
++ len += snprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str);
+
+ if ((str = info->model) != NULL)
+- len += sprintf (buffer + len, "MODEL:%s;\n", str);
++ len += snprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str);
+
+ if ((str = info->mfr) != NULL)
+- len += sprintf (buffer + len, "MANUFACTURER:%s;\n", str);
++ len += snprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str);
+
+ if ((str = info->description) != NULL)
+- len += sprintf (buffer + len, "DESCRIPTION:%s;\n", str);
++ len += snprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str);
+
+ if ((str = info->cmdset) != NULL)
+- len += sprintf (buffer + len, "COMMAND SET:%s;\n", str);
++ len += snprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str);
+
+ if (len > *lenp)
+ len = *lenp;
+@@ -117,7 +117,7 @@ static int do_hardware_base_addr(struct
+ void *result, size_t *lenp, loff_t *ppos)
+ {
+ struct parport *port = (struct parport *)table->extra1;
+- char buffer[20];
++ char buffer[64];
+ int len = 0;
+
+ if (*ppos) {
+@@ -128,7 +128,7 @@ static int do_hardware_base_addr(struct
+ if (write) /* permissions prevent this anyway */
+ return -EACCES;
+
+- len += sprintf (buffer, "%lu\t%lu\n", port->base, port->base_hi);
++ len += snprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi);
+
+ if (len > *lenp)
+ len = *lenp;
+@@ -155,7 +155,7 @@ static int do_hardware_irq(struct ctl_ta
+ if (write) /* permissions prevent this anyway */
+ return -EACCES;
+
+- len += sprintf (buffer, "%d\n", port->irq);
++ len += snprintf (buffer, sizeof(buffer), "%d\n", port->irq);
+
+ if (len > *lenp)
+ len = *lenp;
+@@ -182,7 +182,7 @@ static int do_hardware_dma(struct ctl_ta
+ if (write) /* permissions prevent this anyway */
+ return -EACCES;
+
+- len += sprintf (buffer, "%d\n", port->dma);
++ len += snprintf (buffer, sizeof(buffer), "%d\n", port->dma);
+
+ if (len > *lenp)
+ len = *lenp;
+@@ -213,7 +213,7 @@ static int do_hardware_modes(struct ctl_
+ #define printmode(x) \
+ do { \
+ if (port->modes & PARPORT_MODE_##x) \
+- len += sprintf(buffer + len, "%s%s", f++ ? "," : "", #x); \
++ len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \
+ } while (0)
+ int f = 0;
+ printmode(PCSPP);
--- /dev/null
+From 14cba6ace79627a57fb9058582b03f0ed3832390 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
+Date: Mon, 27 May 2024 16:26:15 +0300
+Subject: hwrng: amd - Convert PCIBIOS_* return codes to errnos
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+commit 14cba6ace79627a57fb9058582b03f0ed3832390 upstream.
+
+amd_rng_mod_init() uses pci_read_config_dword() that returns PCIBIOS_*
+codes. The return code is then returned as is but amd_rng_mod_init() is
+a module_init() function that should return normal errnos.
+
+Convert PCIBIOS_* returns code using pcibios_err_to_errno() into normal
+errno before returning it.
+
+Fixes: 96d63c0297cc ("[PATCH] Add AMD HW RNG driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/hw_random/amd-rng.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/hw_random/amd-rng.c
++++ b/drivers/char/hw_random/amd-rng.c
+@@ -142,8 +142,10 @@ static int __init amd_rng_mod_init(void)
+
+ found:
+ err = pci_read_config_dword(pdev, 0x58, &pmbase);
+- if (err)
++ if (err) {
++ err = pcibios_err_to_errno(err);
+ goto put_dev;
++ }
+
+ pmbase &= 0x0000FF00;
+ if (pmbase == 0) {
--- /dev/null
+From 28b8d7793b8573563b3d45321376f36168d77b1e Mon Sep 17 00:00:00 2001
+From: Niklas Cassel <cassel@kernel.org>
+Date: Wed, 17 Apr 2024 18:42:26 +0200
+Subject: PCI: dw-rockchip: Fix initial PERST# GPIO value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Cassel <cassel@kernel.org>
+
+commit 28b8d7793b8573563b3d45321376f36168d77b1e upstream.
+
+PERST# is active low according to the PCIe specification.
+
+However, the existing pcie-dw-rockchip.c driver does:
+
+ gpiod_set_value(..., 0); msleep(100); gpiod_set_value(..., 1);
+
+when asserting + deasserting PERST#.
+
+This is of course wrong, but because all the device trees for this
+compatible string have also incorrectly marked this GPIO as ACTIVE_HIGH:
+
+ $ git grep -B 10 reset-gpios arch/arm64/boot/dts/rockchip/rk3568*
+ $ git grep -B 10 reset-gpios arch/arm64/boot/dts/rockchip/rk3588*
+
+The actual toggling of PERST# is correct, and we cannot change it anyway,
+since that would break device tree compatibility.
+
+However, this driver does request the GPIO to be initialized as
+GPIOD_OUT_HIGH, which does cause a silly sequence where PERST# gets
+toggled back and forth for no good reason.
+
+Fix this by requesting the GPIO to be initialized as GPIOD_OUT_LOW (which
+for this driver means PERST# asserted).
+
+This will avoid an unnecessary signal change where PERST# gets deasserted
+(by devm_gpiod_get_optional()) and then gets asserted (by
+rockchip_pcie_start_link()) just a few instructions later.
+
+Before patch, debug prints on EP side, when booting RC:
+
+ [ 845.606810] pci: PERST# asserted by host!
+ [ 852.483985] pci: PERST# de-asserted by host!
+ [ 852.503041] pci: PERST# asserted by host!
+ [ 852.610318] pci: PERST# de-asserted by host!
+
+After patch, debug prints on EP side, when booting RC:
+
+ [ 125.107921] pci: PERST# asserted by host!
+ [ 132.111429] pci: PERST# de-asserted by host!
+
+This extra, very short, PERST# assertion + deassertion has been reported to
+cause issues with certain WLAN controllers, e.g. RTL8822CE.
+
+Fixes: 0e898eb8df4e ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver")
+Link: https://lore.kernel.org/linux-pci/20240417164227.398901-1-cassel@kernel.org
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Jianfeng Liu <liujianfeng1994@gmail.com>
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Cc: stable@vger.kernel.org # v5.15+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pcie-dw-rockchip.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
++++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+@@ -148,7 +148,7 @@ static int rockchip_pcie_resource_get(st
+ return PTR_ERR(rockchip->apb_base);
+
+ rockchip->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
+- GPIOD_OUT_HIGH);
++ GPIOD_OUT_LOW);
+ if (IS_ERR(rockchip->rst_gpio))
+ return PTR_ERR(rockchip->rst_gpio);
+
--- /dev/null
+From fea93a3e5d5e6a09eb153866d2ce60ea3287a70d Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu@kernel.org>
+Date: Mon, 1 Jul 2024 20:26:05 +0000
+Subject: PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wei Liu <wei.liu@kernel.org>
+
+commit fea93a3e5d5e6a09eb153866d2ce60ea3287a70d upstream.
+
+The intent of the code snippet is to always return 0 for both
+PCI_INTERRUPT_LINE and PCI_INTERRUPT_PIN.
+
+The check misses PCI_INTERRUPT_PIN. This patch fixes that.
+
+This is discovered by this call in VFIO:
+
+ pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin);
+
+The old code does not set *val to 0 because it misses the check for
+PCI_INTERRUPT_PIN. Garbage is returned in that case.
+
+Fixes: 4daace0d8ce8 ("PCI: hv: Add paravirtual PCI front-end for Microsoft Hyper-V VMs")
+Link: https://lore.kernel.org/linux-pci/20240701202606.129606-1-wei.liu@kernel.org
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Michael Kelley <mhklinux@outlook.com>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pci-hyperv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -707,8 +707,8 @@ static void _hv_pcifront_read_config(str
+ PCI_CAPABILITY_LIST) {
+ /* ROM BARs are unimplemented */
+ *val = 0;
+- } else if (where >= PCI_INTERRUPT_LINE && where + size <=
+- PCI_INTERRUPT_PIN) {
++ } else if ((where >= PCI_INTERRUPT_LINE && where + size <= PCI_INTERRUPT_PIN) ||
++ (where >= PCI_INTERRUPT_PIN && where + size <= PCI_MIN_GNT)) {
+ /*
+ * Interrupt Line and Interrupt PIN are hard-wired to zero
+ * because this front-end only supports message-signaled
--- /dev/null
+From 840b7a5edf88fe678c60dee88a135647c0ea4375 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Tue, 16 Apr 2024 11:12:35 +0530
+Subject: PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+commit 840b7a5edf88fe678c60dee88a135647c0ea4375 upstream.
+
+Rockchip platforms use 'GPIO_ACTIVE_HIGH' flag in the devicetree definition
+for ep_gpio. This means, whatever the logical value set by the driver for
+the ep_gpio, physical line will output the same logic level.
+
+For instance,
+
+ gpiod_set_value_cansleep(rockchip->ep_gpio, 0); --> Level low
+ gpiod_set_value_cansleep(rockchip->ep_gpio, 1); --> Level high
+
+But while requesting the ep_gpio, GPIOD_OUT_HIGH flag is currently used.
+Now, this also causes the physical line to output 'high' creating trouble
+for endpoint devices during host reboot.
+
+When host reboot happens, the ep_gpio will initially output 'low' due to
+the GPIO getting reset to its POR value. Then during host controller probe,
+it will output 'high' due to GPIOD_OUT_HIGH flag. Then during
+rockchip_pcie_host_init_port(), it will first output 'low' and then 'high'
+indicating the completion of controller initialization.
+
+On the endpoint side, each output 'low' of ep_gpio is accounted for PERST#
+assert and 'high' for PERST# deassert. With the above mentioned flow during
+host reboot, endpoint will witness below state changes for PERST#:
+
+ (1) PERST# assert - GPIO POR state
+ (2) PERST# deassert - GPIOD_OUT_HIGH while requesting GPIO
+ (3) PERST# assert - rockchip_pcie_host_init_port()
+ (4) PERST# deassert - rockchip_pcie_host_init_port()
+
+Now the time interval between (2) and (3) is very short as both happen
+during the driver probe(), and this results in a race in the endpoint.
+Because, before completing the PERST# deassertion in (2), endpoint got
+another PERST# assert in (3).
+
+A proper way to fix this issue is to change the GPIOD_OUT_HIGH flag in (2)
+to GPIOD_OUT_LOW. Because the usual convention is to request the GPIO with
+a state corresponding to its 'initial/default' value and let the driver
+change the state of the GPIO when required.
+
+As per that, the ep_gpio should be requested with GPIOD_OUT_LOW as it
+corresponds to the POR value of '0' (PERST# assert in the endpoint). Then
+the driver can change the state of the ep_gpio later in
+rockchip_pcie_host_init_port() as per the initialization sequence.
+
+This fixes the firmware crash issue in Qcom based modems connected to
+Rockpro64 based board.
+
+Fixes: e77f847df54c ("PCI: rockchip: Add Rockchip PCIe controller support")
+Closes: https://lore.kernel.org/mhi/20240402045647.GG2933@thinkpad/
+Link: https://lore.kernel.org/linux-pci/20240416-pci-rockchip-perst-fix-v1-1-4800b1d4d954@linaro.org
+Reported-by: Slark Xiao <slark_xiao@163.com>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Cc: stable@vger.kernel.org # v4.9
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-rockchip.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/pcie-rockchip.c
++++ b/drivers/pci/controller/pcie-rockchip.c
+@@ -120,7 +120,7 @@ int rockchip_pcie_parse_dt(struct rockch
+
+ if (rockchip->is_rc) {
+ rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep",
+- GPIOD_OUT_HIGH);
++ GPIOD_OUT_LOW);
+ if (IS_ERR(rockchip->ep_gpio))
+ return dev_err_probe(dev, PTR_ERR(rockchip->ep_gpio),
+ "failed to get ep GPIO\n");
alsa-usb-audio-fix-microphone-sound-on-hd-webcam.patch
alsa-usb-audio-move-hd-webcam-quirk-to-the-right-place.patch
alsa-usb-audio-add-a-quirk-for-sonix-hd-usb-camera.patch
+tools-memory-model-fix-bug-in-lock.cat.patch
+hwrng-amd-convert-pcibios_-return-codes-to-errnos.patch
+pci-hv-return-zero-not-garbage-when-reading-pci_interrupt_pin.patch
+pci-dw-rockchip-fix-initial-perst-gpio-value.patch
+pci-rockchip-use-gpiod_out_low-flag-while-requesting-ep_gpio.patch
+binder-fix-hang-of-unregistered-readers.patch
+dev-parport-fix-the-array-out-of-bounds-risk.patch
--- /dev/null
+From 4c830eef806679dc243e191f962c488dd9d00708 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 6 Jun 2024 09:57:55 -0400
+Subject: tools/memory-model: Fix bug in lock.cat
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 4c830eef806679dc243e191f962c488dd9d00708 upstream.
+
+Andrea reported that the following innocuous litmus test:
+
+C T
+
+{}
+
+P0(spinlock_t *x)
+{
+ int r0;
+
+ spin_lock(x);
+ spin_unlock(x);
+ r0 = spin_is_locked(x);
+}
+
+gives rise to a nonsensical empty result with no executions:
+
+$ herd7 -conf linux-kernel.cfg T.litmus
+Test T Required
+States 0
+Ok
+Witnesses
+Positive: 0 Negative: 0
+Condition forall (true)
+Observation T Never 0 0
+Time T 0.00
+Hash=6fa204e139ddddf2cb6fa963bad117c0
+
+The problem is caused by a bug in the lock.cat part of the LKMM. Its
+computation of the rf relation for RU (read-unlocked) events is
+faulty; it implicitly assumes that every RU event must read from
+either a UL (unlock) event in another thread or from the lock's
+initial state. Neither is true in the litmus test above, so the
+computation yields no possible executions.
+
+The lock.cat code tries to make up for this deficiency by allowing RU
+events outside of critical sections to read from the last po-previous
+UL event. But it does this incorrectly, trying to keep these rfi links
+separate from the rfe links that might also be needed, and passing only
+the latter to herd7's cross() macro.
+
+The problem is fixed by merging the two sets of possible rf links for
+RU events and using them all in the call to cross().
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: Andrea Parri <parri.andrea@gmail.com>
+Closes: https://lore.kernel.org/linux-arch/ZlC0IkzpQdeGj+a3@andrea/
+Tested-by: Andrea Parri <parri.andrea@gmail.com>
+Acked-by: Andrea Parri <parri.andrea@gmail.com>
+Fixes: 15553dcbca06 ("tools/memory-model: Add model support for spin_is_locked()")
+CC: <stable@vger.kernel.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/memory-model/lock.cat | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/tools/memory-model/lock.cat
++++ b/tools/memory-model/lock.cat
+@@ -102,19 +102,19 @@ let rf-lf = rfe-lf | rfi-lf
+ * within one of the lock's critical sections returns False.
+ *)
+
+-(* rfi for RU events: an RU may read from the last po-previous UL *)
+-let rfi-ru = ([UL] ; po-loc ; [RU]) \ ([UL] ; po-loc ; [LKW] ; po-loc)
+-
+-(* rfe for RU events: an RU may read from an external UL or the initial write *)
+-let all-possible-rfe-ru =
+- let possible-rfe-ru r =
++(*
++ * rf for RU events: an RU may read from an external UL or the initial write,
++ * or from the last po-previous UL
++ *)
++let all-possible-rf-ru =
++ let possible-rf-ru r =
+ let pair-to-relation p = p ++ 0
+- in map pair-to-relation (((UL | IW) * {r}) & loc & ext)
+- in map possible-rfe-ru RU
++ in map pair-to-relation ((((UL | IW) * {r}) & loc & ext) |
++ (((UL * {r}) & po-loc) \ ([UL] ; po-loc ; [LKW] ; po-loc)))
++ in map possible-rf-ru RU
+
+ (* Generate all rf relations for RU events *)
+-with rfe-ru from cross(all-possible-rfe-ru)
+-let rf-ru = rfe-ru | rfi-ru
++with rf-ru from cross(all-possible-rf-ru)
+
+ (* Final rf relation *)
+ let rf = rf | rf-lf | rf-ru