Patch "cxl/port: Fix @host confusion in cxl_dport_setup_regs()" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    cxl/port: Fix @host confusion in cxl_dport_setup_regs()

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     cxl-port-fix-host-confusion-in-cxl_dport_setup_regs.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 6509b70f8bb4497e57e5f1caae925ea67348edbc
Author: Dan Williams <dan.j.williams@xxxxxxxxx>
Date:   Wed Oct 18 19:16:56 2023 +0200

    cxl/port: Fix @host confusion in cxl_dport_setup_regs()
    
    [ Upstream commit 33d9c987bf8fb68a9292aba7cc4b1711fcb1be4d ]
    
    commit 5d2ffbe4b81a ("cxl/port: Store the downstream port's Component Register mappings in struct cxl_dport")
    
    ...moved the dport component registers from a raw component_reg_phys
    passed in at dport instantiation time to a 'struct cxl_register_map'
    populated with both the component register data *and* the "host" device
    for mapping operations.
    
    While typical CXL switch dports are mapped by their associated 'struct
    cxl_port', an RCH host bridge dport registered by cxl_acpi needs to wait
    until the cxl_mem driver makes the attachment to map the registers. This
    is because there are no intervening 'struct cxl_port' instances between
    the root cxl_port and the endpoint port in an RCH topology.
    
    For now just mark the host as NULL in the RCH dport case until code that
    needs to map the dport registers arrives.
    
    This patch is not flagged for -stable since nothing in the current
    driver uses the dport->comp_map.
    
    Now, I am slightly uneasy that cxl_setup_comp_regs() sets map->host to a
    wrong value and then cxl_dport_setup_regs() fixes it up, but the
    alternatives I came up with are more messy. For example, adding an
    @logdev to 'struct cxl_register_map' that the dev_printk()s can fall
    back to when @host is NULL. I settled on "post-fixup+comment" since it
    is only RCH dports that have this special case where register probing is
    split between a host-bridge RCRB lookup and when cxl_mem_probe() does
    the association of the cxl_memdev and endpoint port.
    
    [moved rename of @comp_map to @reg_map into next patch]
    
    Fixes: 5d2ffbe4b81a ("cxl/port: Store the downstream port's Component Register mappings in struct cxl_dport")
    Signed-off-by: Robert Richter <rrichter@xxxxxxx>
    Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20231018171713.1883517-4-rrichter@xxxxxxx
    Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index c24cfe2271948..2c6001592fe20 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -722,13 +722,23 @@ static int cxl_port_setup_regs(struct cxl_port *port,
 				   component_reg_phys);
 }
 
-static int cxl_dport_setup_regs(struct cxl_dport *dport,
+static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
 				resource_size_t component_reg_phys)
 {
+	int rc;
+
 	if (dev_is_platform(dport->dport_dev))
 		return 0;
-	return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map,
-				   component_reg_phys);
+
+	/*
+	 * use @dport->dport_dev for the context for error messages during
+	 * register probing, and fixup @host after the fact, since @host may be
+	 * NULL.
+	 */
+	rc = cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map,
+				 component_reg_phys);
+	dport->comp_map.host = host;
+	return rc;
 }
 
 static struct cxl_port *__devm_cxl_add_port(struct device *host,
@@ -989,7 +999,16 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
 	if (!dport)
 		return ERR_PTR(-ENOMEM);
 
-	if (rcrb != CXL_RESOURCE_NONE) {
+	dport->dport_dev = dport_dev;
+	dport->port_id = port_id;
+	dport->port = port;
+
+	if (rcrb == CXL_RESOURCE_NONE) {
+		rc = cxl_dport_setup_regs(&port->dev, dport,
+					  component_reg_phys);
+		if (rc)
+			return ERR_PTR(rc);
+	} else {
 		dport->rcrb.base = rcrb;
 		component_reg_phys = __rcrb_to_component(dport_dev, &dport->rcrb,
 							 CXL_RCRB_DOWNSTREAM);
@@ -998,6 +1017,14 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
 			return ERR_PTR(-ENXIO);
 		}
 
+		/*
+		 * RCH @dport is not ready to map until associated with its
+		 * memdev
+		 */
+		rc = cxl_dport_setup_regs(NULL, dport, component_reg_phys);
+		if (rc)
+			return ERR_PTR(rc);
+
 		dport->rch = true;
 	}
 
@@ -1005,14 +1032,6 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
 		dev_dbg(dport_dev, "Component Registers found for dport: %pa\n",
 			&component_reg_phys);
 
-	dport->dport_dev = dport_dev;
-	dport->port_id = port_id;
-	dport->port = port;
-
-	rc = cxl_dport_setup_regs(dport, component_reg_phys);
-	if (rc)
-		return ERR_PTR(rc);
-
 	cond_cxl_root_lock(port);
 	rc = add_dport(port, dport);
 	cond_cxl_root_unlock(port);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux