[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 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |