[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.4] passthrough: allow to suppress SERR and PERR signaling altogether



commit ddcc6488ce84fb4e66361efdd8a438d589870769
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Mon May 12 17:14:46 2014 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon May 12 17:14:46 2014 +0200

    passthrough: allow to suppress SERR and PERR signaling altogether
    
    This is just to have a workaround at hand in case other chipsets (not
    covered by the previous two patches) also have similar issues.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Acked-by: Don Dugger <donald.d.dugger@xxxxxxxxx>
    Acked-by: Tim Deegan <tim@xxxxxxx>
    Acked-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
    master commit: 1a2a390a560e8319a6be98c7ab6cfaebd230f67e
    master date: 2014-04-25 12:13:31 +0200
---
 docs/misc/xen-command-line.markdown |    8 +++
 xen/drivers/passthrough/pci.c       |  113 +++++++++++++++++++++++++++++++++++
 xen/include/xen/pci_regs.h          |    3 +-
 3 files changed, 123 insertions(+), 1 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown 
b/docs/misc/xen-command-line.markdown
index 15aa404..293d5ac 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -754,6 +754,14 @@ Defaults to booting secondary processors.
 
 Default: `on`
 
+### pci
+> `= {no-}serr | {no-}perr`
+
+Disable signaling of SERR (system errors) and/or PERR (parity errors)
+on all PCI devices.
+
+Default: Signaling left as set by firmware.
+
 ### pci-phantom
 > `=[<seg>:]<bus>:<device>,<stride>`
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index ff78142..6a81e0d 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -154,6 +154,115 @@ static void __init parse_phantom_dev(char *str) {
 }
 custom_param("pci-phantom", parse_phantom_dev);
 
+static u16 __read_mostly command_mask;
+static u16 __read_mostly bridge_ctl_mask;
+
+/*
+ * The 'pci' parameter controls certain PCI device aspects.
+ * Optional comma separated value may contain:
+ *
+ *   serr                       don't suppress system errors (default)
+ *   no-serr                    suppress system errors
+ *   perr                       don't suppress parity errors (default)
+ *   no-perr                    suppress parity errors
+ */
+static void __init parse_pci_param(char *s)
+{
+    char *ss;
+
+    do {
+        bool_t on = !!strncmp(s, "no-", 3);
+        u16 cmd_mask = 0, brctl_mask = 0;
+
+        if ( !on )
+            s += 3;
+
+        ss = strchr(s, ',');
+        if ( ss )
+            *ss = '\0';
+
+        if ( !strcmp(s, "serr") )
+        {
+            cmd_mask = PCI_COMMAND_SERR;
+            brctl_mask = PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_DTMR_SERR;
+        }
+        else if ( !strcmp(s, "perr") )
+        {
+            cmd_mask = PCI_COMMAND_PARITY;
+            brctl_mask = PCI_BRIDGE_CTL_PARITY;
+        }
+
+        if ( on )
+        {
+            command_mask &= ~cmd_mask;
+            bridge_ctl_mask &= ~brctl_mask;
+        }
+        else
+        {
+            command_mask |= cmd_mask;
+            bridge_ctl_mask |= brctl_mask;
+        }
+
+        s = ss + 1;
+    } while ( ss );
+}
+custom_param("pci", parse_pci_param);
+
+static void check_pdev(const struct pci_dev *pdev)
+{
+#define PCI_STATUS_CHECK \
+    (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | \
+     PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | \
+     PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)
+    u16 seg = pdev->seg;
+    u8 bus = pdev->bus;
+    u8 dev = PCI_SLOT(pdev->devfn);
+    u8 func = PCI_FUNC(pdev->devfn);
+    u16 val;
+
+    if ( command_mask )
+    {
+        val = pci_conf_read16(seg, bus, dev, func, PCI_COMMAND);
+        if ( val & command_mask )
+            pci_conf_write16(seg, bus, dev, func, PCI_COMMAND,
+                             val & ~command_mask);
+        val = pci_conf_read16(seg, bus, dev, func, PCI_STATUS);
+        if ( val & PCI_STATUS_CHECK )
+        {
+            printk(XENLOG_INFO "%04x:%02x:%02x.%u status %04x -> %04x\n",
+                   seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
+            pci_conf_write16(seg, bus, dev, func, PCI_STATUS,
+                             val & PCI_STATUS_CHECK);
+        }
+    }
+
+    switch ( pci_conf_read8(seg, bus, dev, func, PCI_HEADER_TYPE) & 0x7f )
+    {
+    case PCI_HEADER_TYPE_BRIDGE:
+        if ( !bridge_ctl_mask )
+            break;
+        val = pci_conf_read16(seg, bus, dev, func, PCI_BRIDGE_CONTROL);
+        if ( val & bridge_ctl_mask )
+            pci_conf_write16(seg, bus, dev, func, PCI_BRIDGE_CONTROL,
+                             val & ~bridge_ctl_mask);
+        val = pci_conf_read16(seg, bus, dev, func, PCI_SEC_STATUS);
+        if ( val & PCI_STATUS_CHECK )
+        {
+            printk(XENLOG_INFO
+                   "%04x:%02x:%02x.%u secondary status %04x -> %04x\n",
+                   seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
+            pci_conf_write16(seg, bus, dev, func, PCI_SEC_STATUS,
+                             val & PCI_STATUS_CHECK);
+        }
+        break;
+
+    case PCI_HEADER_TYPE_CARDBUS:
+        /* TODO */
+        break;
+    }
+#undef PCI_STATUS_CHECK
+}
+
 static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
 {
     struct pci_dev *pdev;
@@ -252,6 +361,8 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 
bus, u8 devfn)
             break;
     }
 
+    check_pdev(pdev);
+
     return pdev;
 }
 
@@ -566,6 +677,8 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct 
pci_dev_info *info)
                    seg, bus, slot, func, ctrl);
     }
 
+    check_pdev(pdev);
+
     ret = 0;
     if ( !pdev->domain )
     {
diff --git a/xen/include/xen/pci_regs.h b/xen/include/xen/pci_regs.h
index ce3d691..ecd6124 100644
--- a/xen/include/xen/pci_regs.h
+++ b/xen/include/xen/pci_regs.h
@@ -125,7 +125,7 @@
 #define  PCI_IO_RANGE_TYPE_16  0x00
 #define  PCI_IO_RANGE_TYPE_32  0x01
 #define  PCI_IO_RANGE_MASK     (~0x0fUL)
-#define PCI_SEC_STATUS         0x1e    /* Secondary status register, only bit 
14 used */
+#define PCI_SEC_STATUS         0x1e    /* Secondary status register */
 #define PCI_MEMORY_BASE                0x20    /* Memory range behind */
 #define PCI_MEMORY_LIMIT       0x22
 #define  PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
@@ -152,6 +152,7 @@
 #define  PCI_BRIDGE_CTL_MASTER_ABORT   0x20  /* Report master aborts */
 #define  PCI_BRIDGE_CTL_BUS_RESET      0x40    /* Secondary bus reset */
 #define  PCI_BRIDGE_CTL_FAST_BACK      0x80    /* Fast Back2Back enabled on 
secondary interface */
+#define  PCI_BRIDGE_CTL_DTMR_SERR      0x800   /* SERR upon discard timer 
expiry */
 
 /* Header type 2 (CardBus bridges) */
 #define PCI_CB_CAPABILITY_LIST 0x14
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.4

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.