[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240618084639.1419629-2-ying.huang@intel.com>
Date: Tue, 18 Jun 2024 16:46:37 +0800
From: Huang Ying <ying.huang@...el.com>
To: Dan Williams <dan.j.williams@...el.com>,
Dave Jiang <dave.jiang@...el.com>
Cc: linux-cxl@...r.kernel.org,
linux-kernel@...r.kernel.org,
Huang Ying <ying.huang@...el.com>,
Alison Schofield <alison.schofield@...el.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Jonathan Cameron <Jonathan.Cameron@...wei.com>,
Bharata B Rao <bharata@....com>,
Alistair Popple <apopple@...dia.com>,
"Aneesh Kumar K . V" <aneesh.kumar@...ux.ibm.com>,
Davidlohr Bueso <dave@...olabs.net>,
Vishal Verma <vishal.l.verma@...el.com>,
Ira Weiny <ira.weiny@...el.com>
Subject: [PATCH v3 1/3] cxl/region: Fix a race condition in memory hotplug notifier
In the memory hotplug notifier function of the CXL region,
cxl_region_perf_attrs_callback(), the node ID is obtained by checking
the host address range of the region. However, the address range
information is not available when the region is registered in
devm_cxl_add_region(). Additionally, this information may be removed
or added under the protection of cxl_region_rwsem during runtime. If
the memory notifier is called for nodes other than that backed by the
region, a race condition may occur, potentially leading to a NULL
dereference or an invalid address range.
The race condition is addressed by checking the availability of the
address range information under the protection of cxl_region_rwsem. To
enhance code readability and use guard(), the relevant code has been
moved into a newly added function: cxl_region_nid().
Fixes: 067353a46d8c ("cxl/region: Add memory hotplug notifier for cxl region")
Signed-off-by: "Huang, Ying" <ying.huang@...el.com>
Cc: Dan Williams <dan.j.williams@...el.com>
Cc: Alison Schofield <alison.schofield@...el.com>
Cc: Andrew Morton <akpm@...ux-foundation.org>
Cc: Jonathan Cameron <Jonathan.Cameron@...wei.com>
Cc: Dave Jiang <dave.jiang@...el.com>
Cc: Bharata B Rao <bharata@....com>
Cc: Alistair Popple <apopple@...dia.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@...ux.ibm.com>
Cc: Davidlohr Bueso <dave@...olabs.net>
Cc: Vishal Verma <vishal.l.verma@...el.com>
Cc: Ira Weiny <ira.weiny@...el.com>
---
drivers/cxl/core/region.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 3c2b6144be23..51aeef2c012c 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -2304,14 +2304,25 @@ static bool cxl_region_update_coordinates(struct cxl_region *cxlr, int nid)
return true;
}
+static int cxl_region_nid(struct cxl_region *cxlr)
+{
+ struct cxl_region_params *p = &cxlr->params;
+ struct cxl_endpoint_decoder *cxled;
+ struct cxl_decoder *cxld;
+
+ guard(rwsem_read)(&cxl_region_rwsem);
+ cxled = p->targets[0];
+ if (!cxled)
+ return NUMA_NO_NODE;
+ cxld = &cxled->cxld;
+ return phys_to_target_node(cxld->hpa_range.start);
+}
+
static int cxl_region_perf_attrs_callback(struct notifier_block *nb,
unsigned long action, void *arg)
{
struct cxl_region *cxlr = container_of(nb, struct cxl_region,
memory_notifier);
- struct cxl_region_params *p = &cxlr->params;
- struct cxl_endpoint_decoder *cxled = p->targets[0];
- struct cxl_decoder *cxld = &cxled->cxld;
struct memory_notify *mnb = arg;
int nid = mnb->status_change_nid;
int region_nid;
@@ -2319,7 +2330,7 @@ static int cxl_region_perf_attrs_callback(struct notifier_block *nb,
if (nid == NUMA_NO_NODE || action != MEM_ONLINE)
return NOTIFY_DONE;
- region_nid = phys_to_target_node(cxld->hpa_range.start);
+ region_nid = cxl_region_nid(cxlr);
if (nid != region_nid)
return NOTIFY_DONE;
--
2.39.2
Powered by blists - more mailing lists