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

Re: [Xen-devel] [PATCH] x86/msi: Validate the guest-identified PCI devices in pci_prepare_msix()



On Fri, Jan 24, 2014 at 04:19:15PM +0000, Jan Beulich wrote:
> >>> On 24.01.14 at 16:01, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> 
> >>> wrote:
> > I built the kernel without the igb driver just to eliminate it being
> > the culprit. Now I can boot without issues and this is what lspci
> > reports:
> > 
> > -bash-4.1# lspci -s 02:00.0 -v
> > 02:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network 
> > Connection (rev 01)
> >         Subsystem: Intel Corporation Gigabit ET Dual Port Server Adapter
> >         Flags: bus master, fast devsel, latency 0, IRQ 10
> >         Memory at f1420000 (32-bit, non-prefetchable) [size=128K]
> >         Memory at f1000000 (32-bit, non-prefetchable) [size=4M]
> >         I/O ports at e020 [size=32]
> >         Memory at f1444000 (32-bit, non-prefetchable) [size=16K]
> >         Expansion ROM at f0c00000 [disabled] [size=4M]
> >         Capabilities: [40] Power Management version 3
> >         Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+
> >         Capabilities: [70] MSI-X: Enable- Count=10 Masked-
> 
> So here's a patch to figure out why we don't find this.

Thank you!

See attached log. The corresponding xen-syms is compressed and
updated at : http://darnok.org/xen/xen-syms.gz

The interesting bit is:

(XEN) 02:00.0: status=0010 (alloc_pdev+0xb4/0x2e9 wants 11)
(XEN) 02:00.0: pos=40
(XEN) 02:00.0: id=01
(XEN) 02:00.0: pos=50
(XEN) 02:00.0: id=05
(XEN) 02:00.0: pos=70
(XEN) 02:00.0: id=11
(XEN) 02:00.1: status=0010 (alloc_pdev+0xb4/0x2e9 wants 11)
(XEN) 02:00.1: pos=40
(XEN) 02:00.1: id=01
(XEN) 02:00.1: pos=50
(XEN) 02:00.1: id=05
(XEN) 02:00.1: pos=70
(XEN) 02:00.1: id=11

The diff of the tree is:

diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 284042e..3eadf9f 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -1033,7 +1033,7 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool_t 
off)
 
     spin_lock(&pcidevs_lock);
     pdev = pci_get_pdev(seg, bus, devfn);
-    if ( !pdev )
+    if ( !pdev  || !pdev->msix )
         rc = -ENODEV;
     else if ( pdev->msix->used_entries != !!off )
         rc = -EBUSY;
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index 1040b2c..ff5587b 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -564,7 +564,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) 
arg)
         ret = -EFAULT;
         if ( copy_from_guest(&manage_pci, arg, 1) != 0 )
             break;
-
+        printk("PHYSDEVOP_manage_pci_add of %x:%x.%x\n", manage_pci.bus, 
PCI_SLOT(manage_pci.devfn), PCI_FUNC(manage_pci.devfn));
         ret = pci_add_device(0, manage_pci.bus, manage_pci.devfn, NULL);
         break;
     }
@@ -588,6 +588,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) 
arg)
             break;
 
         ret = -EINVAL;
+        printk("PHYSDEVOP_manage_pci_add_ext of %x:%x.%x %d,%d\n", 
manage_pci_ext.bus, PCI_SLOT(manage_pci_ext.devfn), 
PCI_FUNC(manage_pci_ext.devfn), manage_pci_ext.is_extfn, 
manage_pci_ext.is_virtfn);
         if ( (manage_pci_ext.is_extfn > 1) || (manage_pci_ext.is_virtfn > 1) )
             break;
 
@@ -609,6 +610,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) 
arg)
         if ( copy_from_guest(&add, arg, 1) != 0 )
             break;
 
+        printk("PHYSDEVOP_pci_device_add of %x:%x.%x flags:%x\n", add.bus, 
PCI_SLOT(add.devfn), PCI_FUNC(add.devfn), add.flags);
         pdev_info.is_extfn = !!(add.flags & XEN_PCI_DEV_EXTFN);
         if ( add.flags & XEN_PCI_DEV_VIRTFN )
         {
@@ -639,9 +641,11 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) 
arg)
 
         if ( copy_from_guest(&dev, arg, 1) )
             ret = -EFAULT;
-        else
+        else {
+            printk("PHYSDEVOP_prepare/release_msix of %x:%x.%x \n", dev.bus, 
PCI_SLOT(dev.devfn), PCI_FUNC(dev.devfn));
             ret = pci_prepare_msix(dev.seg, dev.bus, dev.devfn,
                                    cmd != PHYSDEVOP_prepare_msix);
+        }
         break;
     }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index c5c8344..93ba11c 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -172,7 +172,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 
bus, u8 devfn)
     INIT_LIST_HEAD(&pdev->msi_list);
 
     if ( pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                             PCI_CAP_ID_MSIX) )
+                             PCI_CAP_ID_MSIX | 0x80) )
     {
         struct arch_msix *msix = xzalloc(struct arch_msix);
 
diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index 25dc5f1..9f9a371 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -14,19 +14,24 @@ int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, 
u8 cap)
     int max_cap = 48;
     u8 pos = PCI_CAPABILITY_LIST;
     u16 status;
+bool_t log = (cap & 0x80) && !seg && bus == 2;//temp
+cap &= ~0x80;//temp
 
     status = pci_conf_read16(seg, bus, dev, func, PCI_STATUS);
+if(log) printk("02:%02x.%u: status=%04x (%ps wants %02x)\n", dev, func, 
status, __builtin_return_address(0), cap);//temp
     if ( (status & PCI_STATUS_CAP_LIST) == 0 )
         return 0;
 
     while ( max_cap-- )
     {
         pos = pci_conf_read8(seg, bus, dev, func, pos);
+if(log) printk("02:%02x.%u: pos=%02x\n", dev, func, pos);//temp
         if ( pos < 0x40 )
             break;
 
         pos &= ~3;
         id = pci_conf_read8(seg, bus, dev, func, pos + PCI_CAP_LIST_ID);
+if(log) printk("02:%02x.%u: id=%02x\n", dev, func, id);//temp
 
         if ( id == 0xff )
             break;
@@ -35,6 +40,7 @@ int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 
cap)
 
         pos += PCI_CAP_LIST_NEXT;
     }
+if(log) printk("02:%02x.%u: no cap %02x\n", dev, func, cap);//temp
 
     return 0;
 }

Attachment: tst035-jan.txt
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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