@@ -1574,6 +1574,104 @@ static int proc_eeh_show(struct seq_file *m, void *v)
15741574}
15751575#endif /* CONFIG_PROC_FS */
15761576
1577+ static int eeh_break_device (struct pci_dev * pdev )
1578+ {
1579+ struct resource * bar = NULL ;
1580+ void __iomem * mapped ;
1581+ u16 old , bit ;
1582+ int i , pos ;
1583+
1584+ /* Do we have an MMIO BAR to disable? */
1585+ for (i = 0 ; i <= PCI_STD_RESOURCE_END ; i ++ ) {
1586+ struct resource * r = & pdev -> resource [i ];
1587+
1588+ if (!r -> flags || !r -> start )
1589+ continue ;
1590+ if (r -> flags & IORESOURCE_IO )
1591+ continue ;
1592+ if (r -> flags & IORESOURCE_UNSET )
1593+ continue ;
1594+
1595+ bar = r ;
1596+ break ;
1597+ }
1598+
1599+ if (!bar ) {
1600+ pci_err (pdev , "Unable to find Memory BAR to cause EEH with\n" );
1601+ return - ENXIO ;
1602+ }
1603+
1604+ pci_err (pdev , "Going to break: %pR\n" , bar );
1605+
1606+ if (pdev -> is_virtfn ) {
1607+ #ifndef CONFIG_PCI_IOV
1608+ return - ENXIO ;
1609+ #else
1610+ /*
1611+ * VFs don't have a per-function COMMAND register, so the best
1612+ * we can do is clear the Memory Space Enable bit in the PF's
1613+ * SRIOV control reg.
1614+ *
1615+ * Unfortunately, this requires that we have a PF (i.e doesn't
1616+ * work for a passed-through VF) and it has the potential side
1617+ * effect of also causing an EEH on every other VF under the
1618+ * PF. Oh well.
1619+ */
1620+ pdev = pdev -> physfn ;
1621+ if (!pdev )
1622+ return - ENXIO ; /* passed through VFs have no PF */
1623+
1624+ pos = pci_find_ext_capability (pdev , PCI_EXT_CAP_ID_SRIOV );
1625+ pos += PCI_SRIOV_CTRL ;
1626+ bit = PCI_SRIOV_CTRL_MSE ;
1627+ #endif /* !CONFIG_PCI_IOV */
1628+ } else {
1629+ bit = PCI_COMMAND_MEMORY ;
1630+ pos = PCI_COMMAND ;
1631+ }
1632+
1633+ /*
1634+ * Process here is:
1635+ *
1636+ * 1. Disable Memory space.
1637+ *
1638+ * 2. Perform an MMIO to the device. This should result in an error
1639+ * (CA / UR) being raised by the device which results in an EEH
1640+ * PE freeze. Using the in_8() accessor skips the eeh detection hook
1641+ * so the freeze hook so the EEH Detection machinery won't be
1642+ * triggered here. This is to match the usual behaviour of EEH
1643+ * where the HW will asynchronously freeze a PE and it's up to
1644+ * the kernel to notice and deal with it.
1645+ *
1646+ * 3. Turn Memory space back on. This is more important for VFs
1647+ * since recovery will probably fail if we don't. For normal
1648+ * the COMMAND register is reset as a part of re-initialising
1649+ * the device.
1650+ *
1651+ * Breaking stuff is the point so who cares if it's racy ;)
1652+ */
1653+ pci_read_config_word (pdev , pos , & old );
1654+
1655+ mapped = ioremap (bar -> start , PAGE_SIZE );
1656+ if (!mapped ) {
1657+ pci_err (pdev , "Unable to map MMIO BAR %pR\n" , bar );
1658+ return - ENXIO ;
1659+ }
1660+
1661+ pci_write_config_word (pdev , pos , old & ~bit );
1662+ in_8 (mapped );
1663+ pci_write_config_word (pdev , pos , old );
1664+
1665+ iounmap (mapped );
1666+
1667+ return 0 ;
1668+ }
1669+
1670+ int eeh_pe_inject_mmio_error (struct pci_dev * pdev )
1671+ {
1672+ return eeh_break_device (pdev );
1673+ }
1674+
15771675#ifdef CONFIG_DEBUG_FS
15781676
15791677
@@ -1725,99 +1823,6 @@ static const struct file_operations eeh_dev_check_fops = {
17251823 .read = eeh_debugfs_dev_usage ,
17261824};
17271825
1728- static int eeh_debugfs_break_device (struct pci_dev * pdev )
1729- {
1730- struct resource * bar = NULL ;
1731- void __iomem * mapped ;
1732- u16 old , bit ;
1733- int i , pos ;
1734-
1735- /* Do we have an MMIO BAR to disable? */
1736- for (i = 0 ; i <= PCI_STD_RESOURCE_END ; i ++ ) {
1737- struct resource * r = & pdev -> resource [i ];
1738-
1739- if (!r -> flags || !r -> start )
1740- continue ;
1741- if (r -> flags & IORESOURCE_IO )
1742- continue ;
1743- if (r -> flags & IORESOURCE_UNSET )
1744- continue ;
1745-
1746- bar = r ;
1747- break ;
1748- }
1749-
1750- if (!bar ) {
1751- pci_err (pdev , "Unable to find Memory BAR to cause EEH with\n" );
1752- return - ENXIO ;
1753- }
1754-
1755- pci_err (pdev , "Going to break: %pR\n" , bar );
1756-
1757- if (pdev -> is_virtfn ) {
1758- #ifndef CONFIG_PCI_IOV
1759- return - ENXIO ;
1760- #else
1761- /*
1762- * VFs don't have a per-function COMMAND register, so the best
1763- * we can do is clear the Memory Space Enable bit in the PF's
1764- * SRIOV control reg.
1765- *
1766- * Unfortunately, this requires that we have a PF (i.e doesn't
1767- * work for a passed-through VF) and it has the potential side
1768- * effect of also causing an EEH on every other VF under the
1769- * PF. Oh well.
1770- */
1771- pdev = pdev -> physfn ;
1772- if (!pdev )
1773- return - ENXIO ; /* passed through VFs have no PF */
1774-
1775- pos = pci_find_ext_capability (pdev , PCI_EXT_CAP_ID_SRIOV );
1776- pos += PCI_SRIOV_CTRL ;
1777- bit = PCI_SRIOV_CTRL_MSE ;
1778- #endif /* !CONFIG_PCI_IOV */
1779- } else {
1780- bit = PCI_COMMAND_MEMORY ;
1781- pos = PCI_COMMAND ;
1782- }
1783-
1784- /*
1785- * Process here is:
1786- *
1787- * 1. Disable Memory space.
1788- *
1789- * 2. Perform an MMIO to the device. This should result in an error
1790- * (CA / UR) being raised by the device which results in an EEH
1791- * PE freeze. Using the in_8() accessor skips the eeh detection hook
1792- * so the freeze hook so the EEH Detection machinery won't be
1793- * triggered here. This is to match the usual behaviour of EEH
1794- * where the HW will asynchronously freeze a PE and it's up to
1795- * the kernel to notice and deal with it.
1796- *
1797- * 3. Turn Memory space back on. This is more important for VFs
1798- * since recovery will probably fail if we don't. For normal
1799- * the COMMAND register is reset as a part of re-initialising
1800- * the device.
1801- *
1802- * Breaking stuff is the point so who cares if it's racy ;)
1803- */
1804- pci_read_config_word (pdev , pos , & old );
1805-
1806- mapped = ioremap (bar -> start , PAGE_SIZE );
1807- if (!mapped ) {
1808- pci_err (pdev , "Unable to map MMIO BAR %pR\n" , bar );
1809- return - ENXIO ;
1810- }
1811-
1812- pci_write_config_word (pdev , pos , old & ~bit );
1813- in_8 (mapped );
1814- pci_write_config_word (pdev , pos , old );
1815-
1816- iounmap (mapped );
1817-
1818- return 0 ;
1819- }
1820-
18211826static ssize_t eeh_dev_break_write (struct file * filp ,
18221827 const char __user * user_buf ,
18231828 size_t count , loff_t * ppos )
@@ -1829,7 +1834,7 @@ static ssize_t eeh_dev_break_write(struct file *filp,
18291834 if (IS_ERR (pdev ))
18301835 return PTR_ERR (pdev );
18311836
1832- ret = eeh_debugfs_break_device (pdev );
1837+ ret = eeh_break_device (pdev );
18331838 pci_dev_put (pdev );
18341839
18351840 if (ret < 0 )
@@ -1844,11 +1849,6 @@ static const struct file_operations eeh_dev_break_fops = {
18441849 .read = eeh_debugfs_dev_usage ,
18451850};
18461851
1847- int eeh_pe_inject_mmio_error (struct pci_dev * pdev )
1848- {
1849- return eeh_debugfs_break_device (pdev );
1850- }
1851-
18521852static ssize_t eeh_dev_can_recover (struct file * filp ,
18531853 const char __user * user_buf ,
18541854 size_t count , loff_t * ppos )
0 commit comments