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