Commit 7974835a authored by Dave Jiang's avatar Dave Jiang
Browse files

cxl: Add endpoint decoder flags clear when PCI reset happens



When a PCI reset happens, the lock and enable flags of the CXL device
should be cleared to avoid stale state flags after reset. Add flag
clearing during cxl_reset_done() to clear the relevant endpoint
decoder flags for all decoders of the endpoint device.

Reported-by: default avatarDan Williams <dan.j.williams@intel.com>
Reviewed-by: default avatarAlison Schofield <alison.schofield@intel.com>
Reviewed-by: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/20260319152541.2739343-1-dave.jiang@intel.com


Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
parent 1e1cd49d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -333,6 +333,7 @@ int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);
#define CXL_DECODER_F_LOCK  BIT(4)
#define CXL_DECODER_F_ENABLE    BIT(5)
#define CXL_DECODER_F_NORMALIZED_ADDRESSING BIT(6)
#define CXL_DECODER_F_RESET_MASK (CXL_DECODER_F_ENABLE | CXL_DECODER_F_LOCK)

enum cxl_decoder_type {
	CXL_DECODER_DEVMEM = 2,
+16 −0
Original line number Diff line number Diff line
@@ -1030,6 +1030,19 @@ static void cxl_error_resume(struct pci_dev *pdev)
		 dev->driver ? "successful" : "failed");
}

static int cxl_endpoint_decoder_clear_reset_flags(struct device *dev, void *data)
{
	struct cxl_endpoint_decoder *cxled;

	if (!is_endpoint_decoder(dev))
		return 0;

	cxled = to_cxl_endpoint_decoder(dev);
	cxled->cxld.flags &= ~CXL_DECODER_F_RESET_MASK;

	return 0;
}

static void cxl_reset_done(struct pci_dev *pdev)
{
	struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
@@ -1045,6 +1058,9 @@ static void cxl_reset_done(struct pci_dev *pdev)
	guard(device)(&cxlmd->dev);
	if (cxlmd->endpoint &&
	    cxl_endpoint_decoder_reset_detected(cxlmd->endpoint)) {
		device_for_each_child(&cxlmd->endpoint->dev, NULL,
				      cxl_endpoint_decoder_clear_reset_flags);

		dev_crit(dev, "SBR happened without memory regions removal.\n");
		dev_crit(dev, "System may be unstable if regions hosted system memory.\n");
		add_taint(TAINT_USER, LOCKDEP_STILL_OK);