From 24ae6712355eed10432c20eb904f041d44c66f5c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 24 Nov 2023 11:21:13 +0000 Subject: [PATCH] 6.5-stable patches added patches: cxl-port-fix-delete_endpoint-vs-parent-unregistration-race.patch cxl-region-fix-x1-root-decoder-granularity-calculations.patch --- ...dpoint-vs-parent-unregistration-race.patch | 116 ++++++++++++++++++ ...oot-decoder-granularity-calculations.patch | 86 +++++++++++++ queue-6.5/series | 2 + 3 files changed, 204 insertions(+) create mode 100644 queue-6.5/cxl-port-fix-delete_endpoint-vs-parent-unregistration-race.patch create mode 100644 queue-6.5/cxl-region-fix-x1-root-decoder-granularity-calculations.patch 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 index 00000000000..1e5d3cb3793 --- /dev/null +++ b/queue-6.5/cxl-port-fix-delete_endpoint-vs-parent-unregistration-race.patch @@ -0,0 +1,116 @@ +From 8d2ad999ca3c64cb08cf6a58d227b9d9e746d708 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Fri, 27 Oct 2023 20:13:23 -0700 +Subject: cxl/port: Fix delete_endpoint() vs parent unregistration race + +From: Dan Williams + +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: +Reported-by: Robert Richter +Closes: http://lore.kernel.org/r/20231018171713.1883517-2-rrichter@amd.com +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..47f846144e6 --- /dev/null +++ b/queue-6.5/cxl-region-fix-x1-root-decoder-granularity-calculations.patch @@ -0,0 +1,86 @@ +From 98a04c7aced2b43b3ac4befe216c4eecc7257d4b Mon Sep 17 00:00:00 2001 +From: Jim Harris +Date: Thu, 26 Oct 2023 10:09:06 -0700 +Subject: cxl/region: Fix x1 root-decoder granularity calculations + +From: Jim Harris + +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: +Signed-off-by: Jim Harris +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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, diff --git a/queue-6.5/series b/queue-6.5/series index 7ab6e982235..02046ffc625 100644 --- a/queue-6.5/series +++ b/queue-6.5/series @@ -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 -- 2.47.3