Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13e68d8b authored by Daniel Axtens's avatar Daniel Axtens Committed by Michael Ellerman
Browse files

cxl: Allow the kernel to trust that an image won't change on PERST.



Provide a kernel API and a sysfs entry which allow a user to specify
that when a card is PERSTed, it's image will stay the same, allowing
it to participate in EEH.

cxl_reset is used to reflash the card. In that case, we cannot safely
assert that the image will not change. Therefore, disallow cxl_reset
if the flag is set.

Signed-off-by: default avatarDaniel Axtens <dja@axtens.net>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 4e1efb40
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -223,3 +223,13 @@ Description: write only
                Writing 1 will issue a PERST to card which may cause the card
                to reload the FPGA depending on load_image_on_perst.
Users:		https://github.com/ibm-capi/libcxl

What:		/sys/class/cxl/<card>/perst_reloads_same_image
Date:		July 2015
Contact:	linuxppc-dev@lists.ozlabs.org
Description:	read/write
		Trust that when an image is reloaded via PERST, it will not
		have changed.
		0 = don't trust, the image may be different (default)
		1 = trust that the image will not change.
Users:		https://github.com/ibm-capi/libcxl
+7 −0
Original line number Diff line number Diff line
@@ -327,3 +327,10 @@ int cxl_afu_reset(struct cxl_context *ctx)
	return cxl_afu_check_and_enable(afu);
}
EXPORT_SYMBOL_GPL(cxl_afu_reset);

void cxl_perst_reloads_same_image(struct cxl_afu *afu,
				  bool perst_reloads_same_image)
{
	afu->adapter->perst_same_image = perst_reloads_same_image;
}
EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image);
+1 −0
Original line number Diff line number Diff line
@@ -493,6 +493,7 @@ struct cxl {
	bool user_image_loaded;
	bool perst_loads_image;
	bool perst_select_user;
	bool perst_same_image;
};

int cxl_alloc_one_irq(struct cxl *adapter);
+7 −0
Original line number Diff line number Diff line
@@ -878,6 +878,12 @@ int cxl_reset(struct cxl *adapter)
	int i;
	u32 val;

	if (adapter->perst_same_image) {
		dev_warn(&dev->dev,
			 "cxl: refusing to reset/reflash when perst_reloads_same_image is set.\n");
		return -EINVAL;
	}

	dev_info(&dev->dev, "CXL reset\n");

	/* pcie_warm_reset requests a fundamental pci reset which includes a
@@ -1151,6 +1157,7 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
	 * configure/reconfigure
	 */
	adapter->perst_loads_image = true;
	adapter->perst_same_image = false;

	rc = cxl_configure_adapter(adapter, dev);
	if (rc) {
+26 −0
Original line number Diff line number Diff line
@@ -112,12 +112,38 @@ static ssize_t load_image_on_perst_store(struct device *device,
	return count;
}

static ssize_t perst_reloads_same_image_show(struct device *device,
				 struct device_attribute *attr,
				 char *buf)
{
	struct cxl *adapter = to_cxl_adapter(device);

	return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->perst_same_image);
}

static ssize_t perst_reloads_same_image_store(struct device *device,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct cxl *adapter = to_cxl_adapter(device);
	int rc;
	int val;

	rc = sscanf(buf, "%i", &val);
	if ((rc != 1) || !(val == 1 || val == 0))
		return -EINVAL;

	adapter->perst_same_image = (val == 1 ? true : false);
	return count;
}

static struct device_attribute adapter_attrs[] = {
	__ATTR_RO(caia_version),
	__ATTR_RO(psl_revision),
	__ATTR_RO(base_image),
	__ATTR_RO(image_loaded),
	__ATTR_RW(load_image_on_perst),
	__ATTR_RW(perst_reloads_same_image),
	__ATTR(reset, S_IWUSR, NULL, reset_adapter_store),
};

Loading