These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / powerpc / kernel / eeh.c
index cb565ad..40e4d4a 100644 (file)
@@ -144,8 +144,6 @@ struct eeh_stats {
 
 static struct eeh_stats eeh_stats;
 
-#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
-
 static int __init eeh_setup(char *str)
 {
        if (!strcmp(str, "off"))
@@ -353,7 +351,8 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
         * worried about _PAGE_SPLITTING/collapse. Also we will not hit
         * page table free, because of init_mm.
         */
-       ptep = __find_linux_pte_or_hugepte(init_mm.pgd, token, &hugepage_shift);
+       ptep = __find_linux_pte_or_hugepte(init_mm.pgd, token,
+                                          NULL, &hugepage_shift);
        if (!ptep)
                return token;
        WARN_ON(hugepage_shift);
@@ -632,7 +631,7 @@ int eeh_pci_enable(struct eeh_pe *pe, int function)
         */
        switch (function) {
        case EEH_OPT_THAW_MMIO:
-               active_flag = EEH_STATE_MMIO_ACTIVE;
+               active_flag = EEH_STATE_MMIO_ACTIVE | EEH_STATE_MMIO_ENABLED;
                break;
        case EEH_OPT_THAW_DMA:
                active_flag = EEH_STATE_DMA_ACTIVE;
@@ -734,7 +733,7 @@ static void *eeh_restore_dev_state(void *data, void *userdata)
 
        /* The caller should restore state for the specified device */
        if (pdev != dev)
-               pci_save_state(pdev);
+               pci_restore_state(pdev);
 
        return NULL;
 }
@@ -767,14 +766,14 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
                eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
                break;
        case pcie_hot_reset:
-               eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
+               eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED);
                eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
                eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
                eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
                eeh_ops->reset(pe, EEH_RESET_HOT);
                break;
        case pcie_warm_reset:
-               eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
+               eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED);
                eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
                eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
                eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
@@ -1413,8 +1412,7 @@ void eeh_dev_release(struct pci_dev *pdev)
                goto out;
 
        /* Decrease PE's pass through count */
-       atomic_dec(&edev->pe->pass_dev_cnt);
-       WARN_ON(atomic_read(&edev->pe->pass_dev_cnt) < 0);
+       WARN_ON(atomic_dec_if_positive(&edev->pe->pass_dev_cnt) < 0);
        eeh_pe_change_owner(edev->pe);
 out:
        mutex_unlock(&eeh_dev_mutex);
@@ -1427,13 +1425,11 @@ static int dev_has_iommu_table(struct device *dev, void *data)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct pci_dev **ppdev = data;
-       struct iommu_table *tbl;
 
        if (!dev)
                return 0;
 
-       tbl = get_iommu_table_base(dev);
-       if (tbl && tbl->it_group) {
+       if (dev->iommu_group) {
                *ppdev = pdev;
                return 1;
        }
@@ -1662,6 +1658,41 @@ int eeh_pe_configure(struct eeh_pe *pe)
 }
 EXPORT_SYMBOL_GPL(eeh_pe_configure);
 
+/**
+ * eeh_pe_inject_err - Injecting the specified PCI error to the indicated PE
+ * @pe: the indicated PE
+ * @type: error type
+ * @function: error function
+ * @addr: address
+ * @mask: address mask
+ *
+ * The routine is called to inject the specified PCI error, which
+ * is determined by @type and @function, to the indicated PE for
+ * testing purpose.
+ */
+int eeh_pe_inject_err(struct eeh_pe *pe, int type, int func,
+                     unsigned long addr, unsigned long mask)
+{
+       /* Invalid PE ? */
+       if (!pe)
+               return -ENODEV;
+
+       /* Unsupported operation ? */
+       if (!eeh_ops || !eeh_ops->err_inject)
+               return -ENOENT;
+
+       /* Check on PCI error type */
+       if (type != EEH_ERR_TYPE_32 && type != EEH_ERR_TYPE_64)
+               return -EINVAL;
+
+       /* Check on PCI error function */
+       if (func < EEH_ERR_FUNC_MIN || func > EEH_ERR_FUNC_MAX)
+               return -EINVAL;
+
+       return eeh_ops->err_inject(pe, type, func, addr, mask);
+}
+EXPORT_SYMBOL_GPL(eeh_pe_inject_err);
+
 static int proc_eeh_show(struct seq_file *m, void *v)
 {
        if (!eeh_enabled()) {