]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Nov 2023 11:21:13 +0000 (11:21 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Nov 2023 11:21:13 +0000 (11:21 +0000)
added patches:
cxl-port-fix-delete_endpoint-vs-parent-unregistration-race.patch
cxl-region-fix-x1-root-decoder-granularity-calculations.patch

queue-6.5/cxl-port-fix-delete_endpoint-vs-parent-unregistration-race.patch [new file with mode: 0644]
queue-6.5/cxl-region-fix-x1-root-decoder-granularity-calculations.patch [new file with mode: 0644]
queue-6.5/series

diff --git a/queue-6.5/cxl-port-fix-delete_endpoint-vs-parent-unregistration-race.patch b/queue-6.5/cxl-port-fix-delete_endpoint-vs-parent-unregistration-race.patch
new file mode 100644 (file)
index 0000000..1e5d3cb
--- /dev/null
@@ -0,0 +1,116 @@
+From 8d2ad999ca3c64cb08cf6a58d227b9d9e746d708 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Fri, 27 Oct 2023 20:13:23 -0700
+Subject: cxl/port: Fix delete_endpoint() vs parent unregistration race
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 8d2ad999ca3c64cb08cf6a58d227b9d9e746d708 upstream.
+
+The CXL subsystem, at cxl_mem ->probe() time, establishes a lineage of
+ports (struct cxl_port objects) between an endpoint and the root of a
+CXL topology. Each port including the endpoint port is attached to the
+cxl_port driver.
+
+Given that setup, it follows that when either any port in that lineage
+goes through a cxl_port ->remove() event, or the memdev goes through a
+cxl_mem ->remove() event. The hierarchy below the removed port, or the
+entire hierarchy if the memdev is removed needs to come down.
+
+The delete_endpoint() callback is careful to check whether it is being
+called to tear down the hierarchy, or if it is only being called to
+teardown the memdev because an ancestor port is going through
+->remove().
+
+That care needs to take the device_lock() of the endpoint's parent.
+Which requires 2 bugs to be fixed:
+
+1/ A reference on the parent is needed to prevent use-after-free
+   scenarios like this signature:
+
+    BUG: spinlock bad magic on CPU#0, kworker/u56:0/11
+    Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20230524-3.fc38 05/24/2023
+    Workqueue: cxl_port detach_memdev [cxl_core]
+    RIP: 0010:spin_bug+0x65/0xa0
+    Call Trace:
+      do_raw_spin_lock+0x69/0xa0
+     __mutex_lock+0x695/0xb80
+     delete_endpoint+0xad/0x150 [cxl_core]
+     devres_release_all+0xb8/0x110
+     device_unbind_cleanup+0xe/0x70
+     device_release_driver_internal+0x1d2/0x210
+     detach_memdev+0x15/0x20 [cxl_core]
+     process_one_work+0x1e3/0x4c0
+     worker_thread+0x1dd/0x3d0
+
+2/ In the case of RCH topologies, the parent device that needs to be
+   locked is not always @port->dev as returned by cxl_mem_find_port(), use
+   endpoint->dev.parent instead.
+
+Fixes: 8dd2bc0f8e02 ("cxl/mem: Add the cxl_mem driver")
+Cc: <stable@vger.kernel.org>
+Reported-by: Robert Richter <rrichter@amd.com>
+Closes: http://lore.kernel.org/r/20231018171713.1883517-2-rrichter@amd.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/port.c |   34 +++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -1242,35 +1242,39 @@ static struct device *grandparent(struct
+       return NULL;
+ }
++static struct device *endpoint_host(struct cxl_port *endpoint)
++{
++      struct cxl_port *port = to_cxl_port(endpoint->dev.parent);
++
++      if (is_cxl_root(port))
++              return port->uport_dev;
++      return &port->dev;
++}
++
+ static void delete_endpoint(void *data)
+ {
+       struct cxl_memdev *cxlmd = data;
+       struct cxl_port *endpoint = cxlmd->endpoint;
+-      struct cxl_port *parent_port;
+-      struct device *parent;
++      struct device *host = endpoint_host(endpoint);
+-      parent_port = cxl_mem_find_port(cxlmd, NULL);
+-      if (!parent_port)
+-              goto out;
+-      parent = &parent_port->dev;
+-
+-      device_lock(parent);
+-      if (parent->driver && !endpoint->dead) {
+-              devm_release_action(parent, cxl_unlink_parent_dport, endpoint);
+-              devm_release_action(parent, cxl_unlink_uport, endpoint);
+-              devm_release_action(parent, unregister_port, endpoint);
++      device_lock(host);
++      if (host->driver && !endpoint->dead) {
++              devm_release_action(host, cxl_unlink_parent_dport, endpoint);
++              devm_release_action(host, cxl_unlink_uport, endpoint);
++              devm_release_action(host, unregister_port, endpoint);
+       }
+       cxlmd->endpoint = NULL;
+-      device_unlock(parent);
+-      put_device(parent);
+-out:
++      device_unlock(host);
+       put_device(&endpoint->dev);
++      put_device(host);
+ }
+ int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
+ {
++      struct device *host = endpoint_host(endpoint);
+       struct device *dev = &cxlmd->dev;
++      get_device(host);
+       get_device(&endpoint->dev);
+       cxlmd->endpoint = endpoint;
+       cxlmd->depth = endpoint->depth;
diff --git a/queue-6.5/cxl-region-fix-x1-root-decoder-granularity-calculations.patch b/queue-6.5/cxl-region-fix-x1-root-decoder-granularity-calculations.patch
new file mode 100644 (file)
index 0000000..47f8461
--- /dev/null
@@ -0,0 +1,86 @@
+From 98a04c7aced2b43b3ac4befe216c4eecc7257d4b Mon Sep 17 00:00:00 2001
+From: Jim Harris <jim.harris@samsung.com>
+Date: Thu, 26 Oct 2023 10:09:06 -0700
+Subject: cxl/region: Fix x1 root-decoder granularity calculations
+
+From: Jim Harris <jim.harris@samsung.com>
+
+commit 98a04c7aced2b43b3ac4befe216c4eecc7257d4b upstream.
+
+Root decoder granularity must match value from CFWMS, which may not
+be the region's granularity for non-interleaved root decoders.
+
+So when calculating granularities for host bridge decoders, use the
+region's granularity instead of the root decoder's granularity to ensure
+the correct granularities are set for the host bridge decoders and any
+downstream switch decoders.
+
+Test configuration is 1 host bridge * 2 switches * 2 endpoints per switch.
+
+Region created with 2048 granularity using following command line:
+
+cxl create-region -m -d decoder0.0 -w 4 mem0 mem2 mem1 mem3 \
+                 -g 2048 -s 2048M
+
+Use "cxl list -PDE | grep granularity" to get a view of the granularity
+set at each level of the topology.
+
+Before this patch:
+        "interleave_granularity":2048,
+        "interleave_granularity":2048,
+    "interleave_granularity":512,
+        "interleave_granularity":2048,
+        "interleave_granularity":2048,
+    "interleave_granularity":512,
+"interleave_granularity":256,
+
+After:
+        "interleave_granularity":2048,
+        "interleave_granularity":2048,
+    "interleave_granularity":4096,
+        "interleave_granularity":2048,
+        "interleave_granularity":2048,
+    "interleave_granularity":4096,
+"interleave_granularity":2048,
+
+Fixes: 27b3f8d13830 ("cxl/region: Program target lists")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jim Harris <jim.harris@samsung.com>
+Link: https://lore.kernel.org/r/169824893473.1403938.16110924262989774582.stgit@bgt-140510-bm03.eng.stellus.in
+[djbw: fixup the prebuilt cxl_test region]
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/region.c    |    9 ++++++++-
+ tools/testing/cxl/test/cxl.c |    2 +-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1127,7 +1127,14 @@ static int cxl_port_setup_targets(struct
+       }
+       if (is_cxl_root(parent_port)) {
+-              parent_ig = cxlrd->cxlsd.cxld.interleave_granularity;
++              /*
++               * Root decoder IG is always set to value in CFMWS which
++               * may be different than this region's IG.  We can use the
++               * region's IG here since interleave_granularity_store()
++               * does not allow interleaved host-bridges with
++               * root IG != region IG.
++               */
++              parent_ig = p->interleave_granularity;
+               parent_iw = cxlrd->cxlsd.cxld.interleave_ways;
+               /*
+                * For purposes of address bit routing, use power-of-2 math for
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -831,7 +831,7 @@ static void mock_init_hdm_decoder(struct
+                       cxld->interleave_ways = 2;
+               else
+                       cxld->interleave_ways = 1;
+-              cxld->interleave_granularity = 256;
++              cxld->interleave_granularity = 4096;
+               cxld->hpa_range = (struct range) {
+                       .start = base,
+                       .end = base + size - 1,
index 7ab6e982235e4bacc64580e9a5d2a607c6969c4f..02046ffc625e2329d6945540b7f954a754f2ccf2 100644 (file)
@@ -360,3 +360,5 @@ i3c-master-svc-fix-ibi-may-not-return-mandatory-data-byte.patch
 i3c-master-svc-fix-check-wrong-status-register-in-irq-handler.patch
 i3c-master-svc-fix-sda-keep-low-when-polling-ibiwon-timeout-happen.patch
 i3c-master-svc-fix-random-hot-join-failure-since-timeout-error.patch
+cxl-region-fix-x1-root-decoder-granularity-calculations.patch
+cxl-port-fix-delete_endpoint-vs-parent-unregistration-race.patch