cxl: Allow the kernel to trust that an image won't change on PERST.
authorDaniel Axtens <dja@axtens.net>
Fri, 14 Aug 2015 07:41:25 +0000 (17:41 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 14 Aug 2015 11:32:07 +0000 (21:32 +1000)
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>
Documentation/ABI/testing/sysfs-class-cxl
drivers/misc/cxl/api.c
drivers/misc/cxl/cxl.h
drivers/misc/cxl/pci.c
drivers/misc/cxl/sysfs.c
include/misc/cxl.h

index acfe9df83139a935bca0bde7c3701ff24b147216..b07e86d4597f2196207b9f0e14617e4bcd461d44 100644 (file)
@@ -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
index 729e0851167df9d441a5d26b34256029dd6db3c8..6a768a9ad22f9f840fbeeb8c6189385c9921d6d3 100644 (file)
@@ -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);
index d540542f99316cc17ef454bb9d5a942ede1b298d..cda02412b01e52dc0272d71ad330682469a548f1 100644 (file)
@@ -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);
index 2b61cb1ee62ce814f2a1aa28f6c2c664b1bf40f6..bfbd6478c0c5e87b7bb2413230150456ee61159c 100644 (file)
@@ -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) {
index 31f38bc71a3d5d113263998141b62c4b9285d343..6619cf1f6e1f2bef5275d8b37008fdf36bef0881 100644 (file)
@@ -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),
 };
 
index 7a6c1d6cc1732e1fc83432cd46e65ed25a5fa4ef..f2ffe5bd720dead644c69fb74367adb13c3de026 100644 (file)
@@ -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,
                           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 */