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: Daniel Axtens <dja@axtens.net> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
4e1efb403c
commit
13e68d8bd0
|
@ -223,3 +223,13 @@ Description: write only
|
||||||
Writing 1 will issue a PERST to card which may cause the card
|
Writing 1 will issue a PERST to card which may cause the card
|
||||||
to reload the FPGA depending on load_image_on_perst.
|
to reload the FPGA depending on load_image_on_perst.
|
||||||
Users: https://github.com/ibm-capi/libcxl
|
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
|
||||||
|
|
|
@ -327,3 +327,10 @@ int cxl_afu_reset(struct cxl_context *ctx)
|
||||||
return cxl_afu_check_and_enable(afu);
|
return cxl_afu_check_and_enable(afu);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cxl_afu_reset);
|
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);
|
||||||
|
|
|
@ -493,6 +493,7 @@ struct cxl {
|
||||||
bool user_image_loaded;
|
bool user_image_loaded;
|
||||||
bool perst_loads_image;
|
bool perst_loads_image;
|
||||||
bool perst_select_user;
|
bool perst_select_user;
|
||||||
|
bool perst_same_image;
|
||||||
};
|
};
|
||||||
|
|
||||||
int cxl_alloc_one_irq(struct cxl *adapter);
|
int cxl_alloc_one_irq(struct cxl *adapter);
|
||||||
|
|
|
@ -878,6 +878,12 @@ int cxl_reset(struct cxl *adapter)
|
||||||
int i;
|
int i;
|
||||||
u32 val;
|
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");
|
dev_info(&dev->dev, "CXL reset\n");
|
||||||
|
|
||||||
/* pcie_warm_reset requests a fundamental pci reset which includes a
|
/* 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
|
* configure/reconfigure
|
||||||
*/
|
*/
|
||||||
adapter->perst_loads_image = true;
|
adapter->perst_loads_image = true;
|
||||||
|
adapter->perst_same_image = false;
|
||||||
|
|
||||||
rc = cxl_configure_adapter(adapter, dev);
|
rc = cxl_configure_adapter(adapter, dev);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
|
|
@ -112,12 +112,38 @@ static ssize_t load_image_on_perst_store(struct device *device,
|
||||||
return count;
|
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[] = {
|
static struct device_attribute adapter_attrs[] = {
|
||||||
__ATTR_RO(caia_version),
|
__ATTR_RO(caia_version),
|
||||||
__ATTR_RO(psl_revision),
|
__ATTR_RO(psl_revision),
|
||||||
__ATTR_RO(base_image),
|
__ATTR_RO(base_image),
|
||||||
__ATTR_RO(image_loaded),
|
__ATTR_RO(image_loaded),
|
||||||
__ATTR_RW(load_image_on_perst),
|
__ATTR_RW(load_image_on_perst),
|
||||||
|
__ATTR_RW(perst_reloads_same_image),
|
||||||
__ATTR(reset, S_IWUSR, NULL, reset_adapter_store),
|
__ATTR(reset, S_IWUSR, NULL, reset_adapter_store),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -200,4 +200,14 @@ unsigned int cxl_fd_poll(struct file *file, struct poll_table_struct *poll);
|
||||||
ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
|
ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
|
||||||
loff_t *off);
|
loff_t *off);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For EEH, a driver may want to assert a PERST will reload the same image
|
||||||
|
* from flash into the FPGA.
|
||||||
|
*
|
||||||
|
* This is a property of the entire adapter, not a single AFU, so drivers
|
||||||
|
* should set this property with care!
|
||||||
|
*/
|
||||||
|
void cxl_perst_reloads_same_image(struct cxl_afu *afu,
|
||||||
|
bool perst_reloads_same_image);
|
||||||
|
|
||||||
#endif /* _MISC_CXL_H */
|
#endif /* _MISC_CXL_H */
|
||||||
|
|
Loading…
Reference in New Issue