aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/cxl
diff options
context:
space:
mode:
authorDaniel Axtens <dja@axtens.net>2015-08-14 03:41:25 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-08-14 07:32:07 -0400
commit13e68d8bd05c998cae452a4f3400af1e8edd852e (patch)
treed17ff97c9f46a663b5cb4916fc333703b2cdfea4 /drivers/misc/cxl
parent4e1efb403c1c016ae831bd9988a7d2e5e0af41a0 (diff)
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>
Diffstat (limited to 'drivers/misc/cxl')
-rw-r--r--drivers/misc/cxl/api.c7
-rw-r--r--drivers/misc/cxl/cxl.h1
-rw-r--r--drivers/misc/cxl/pci.c7
-rw-r--r--drivers/misc/cxl/sysfs.c26
4 files changed, 41 insertions, 0 deletions
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
index 729e0851167d..6a768a9ad22f 100644
--- a/drivers/misc/cxl/api.c
+++ b/drivers/misc/cxl/api.c
@@ -327,3 +327,10 @@ int cxl_afu_reset(struct cxl_context *ctx)
327 return cxl_afu_check_and_enable(afu); 327 return cxl_afu_check_and_enable(afu);
328} 328}
329EXPORT_SYMBOL_GPL(cxl_afu_reset); 329EXPORT_SYMBOL_GPL(cxl_afu_reset);
330
331void cxl_perst_reloads_same_image(struct cxl_afu *afu,
332 bool perst_reloads_same_image)
333{
334 afu->adapter->perst_same_image = perst_reloads_same_image;
335}
336EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image);
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index d540542f9931..cda02412b01e 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -493,6 +493,7 @@ struct cxl {
493 bool user_image_loaded; 493 bool user_image_loaded;
494 bool perst_loads_image; 494 bool perst_loads_image;
495 bool perst_select_user; 495 bool perst_select_user;
496 bool perst_same_image;
496}; 497};
497 498
498int cxl_alloc_one_irq(struct cxl *adapter); 499int cxl_alloc_one_irq(struct cxl *adapter);
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 2b61cb1ee62c..bfbd6478c0c5 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -878,6 +878,12 @@ int cxl_reset(struct cxl *adapter)
878 int i; 878 int i;
879 u32 val; 879 u32 val;
880 880
881 if (adapter->perst_same_image) {
882 dev_warn(&dev->dev,
883 "cxl: refusing to reset/reflash when perst_reloads_same_image is set.\n");
884 return -EINVAL;
885 }
886
881 dev_info(&dev->dev, "CXL reset\n"); 887 dev_info(&dev->dev, "CXL reset\n");
882 888
883 /* pcie_warm_reset requests a fundamental pci reset which includes a 889 /* 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)
1151 * configure/reconfigure 1157 * configure/reconfigure
1152 */ 1158 */
1153 adapter->perst_loads_image = true; 1159 adapter->perst_loads_image = true;
1160 adapter->perst_same_image = false;
1154 1161
1155 rc = cxl_configure_adapter(adapter, dev); 1162 rc = cxl_configure_adapter(adapter, dev);
1156 if (rc) { 1163 if (rc) {
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
index 31f38bc71a3d..6619cf1f6e1f 100644
--- a/drivers/misc/cxl/sysfs.c
+++ b/drivers/misc/cxl/sysfs.c
@@ -112,12 +112,38 @@ static ssize_t load_image_on_perst_store(struct device *device,
112 return count; 112 return count;
113} 113}
114 114
115static ssize_t perst_reloads_same_image_show(struct device *device,
116 struct device_attribute *attr,
117 char *buf)
118{
119 struct cxl *adapter = to_cxl_adapter(device);
120
121 return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->perst_same_image);
122}
123
124static ssize_t perst_reloads_same_image_store(struct device *device,
125 struct device_attribute *attr,
126 const char *buf, size_t count)
127{
128 struct cxl *adapter = to_cxl_adapter(device);
129 int rc;
130 int val;
131
132 rc = sscanf(buf, "%i", &val);
133 if ((rc != 1) || !(val == 1 || val == 0))
134 return -EINVAL;
135
136 adapter->perst_same_image = (val == 1 ? true : false);
137 return count;
138}
139
115static struct device_attribute adapter_attrs[] = { 140static struct device_attribute adapter_attrs[] = {
116 __ATTR_RO(caia_version), 141 __ATTR_RO(caia_version),
117 __ATTR_RO(psl_revision), 142 __ATTR_RO(psl_revision),
118 __ATTR_RO(base_image), 143 __ATTR_RO(base_image),
119 __ATTR_RO(image_loaded), 144 __ATTR_RO(image_loaded),
120 __ATTR_RW(load_image_on_perst), 145 __ATTR_RW(load_image_on_perst),
146 __ATTR_RW(perst_reloads_same_image),
121 __ATTR(reset, S_IWUSR, NULL, reset_adapter_store), 147 __ATTR(reset, S_IWUSR, NULL, reset_adapter_store),
122}; 148};
123 149