PCI updates for v3.11:
Hotplug PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device PCI: hotplug: Convert to be builtin only, not modular PCI: pciehp: Convert pciehp to be builtin only, not modular Resource allocation PCI: Retry allocation of only the resource type that failed ARM PCI: mvebu: Disable prefetchable memory support in PCI-to-PCI bridge -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJR+/RRAAoJEFmIoMA60/r8iloP/is7mx667v9F9WRlYMJss+ig K0cVOauokmr/pyS7Tgr0jfhtulXOmN/VJTvCw6h7+qYtsO/DQ7Y5LPXoMW83s5hK /N33HDZcm2/1hUxv/4GS3omtO9VefWcmzXmPM7l1fEBQyACTg/zj1Mb97U8j8mhh vr6y/pLDLwwaRcQNP/Y2F6H8RsDDWE/IyC9MN1qEz+b7Qve5fAPPrDBgExakzmu/ UiiJV3nl7fqBeITA/LSWDCgsOeavmmabqZuaXnKWN0L5PaEa3/8Of6kbsG5ZGgdZ Y5/Qu0HRtAhaFNAd1670IzcMThC6TJV685z09/OQ+4uKpZ2jJYM26ISSdiMG2He4 FQmLQcgkxGX0xYxdD7K37VC7O17NH+3jEouM2SNSCXGz5RQ3qvW5F4IvSctHmIO8 Q0m2HladNYHtOYk1eGNSlxPd3U0nyQwlXSTgJrKYd/cJgUqYjs+Q9zuAmUj+4QPR ywwO3rgpetaROY6avw31fWFGqQFAQEQeXvMwTrAJbdIcxvVz77yRiOrD72X61Z7h A6owzbMmuYKPuym5EbBr0GoCJWAuHc8GIvXKHQQ9QMGuRAj9X4Qrk+BdudeqlTxD e9WKkKGPmPxR6IuSlZdLCNqcTDDlQZFTnq5WJ989pPsUMKFu8LjybKntBEbPtIue ydWvibCrxNbTEMyyg+c6 =z2eX -----END PGP SIGNATURE----- Merge tag 'pci-v3.11-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI fixes from Bjorn Helgaas: "Yinghai fixed a couple regressions: one resource assignment problem introduced in v3.10 that showed up with SR-IOV on powerpc, and another SR-IOV hot-remove issue related to refcounting changes we merged for v3.11. Yinghai is still working on another SR-IOV-related fix or two, which will be simpler if pciehp is non-modular, so I included the Kconfig changes now to get them in earlier. Finally, a minor fix for the ARM Marvell EBU host bridge driver that was merged for v3.11 Hotplug: PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device PCI: hotplug: Convert to be builtin only, not modular PCI: pciehp: Convert pciehp to be builtin only, not modular Resource allocation: PCI: Retry allocation of only the resource type that failed ARM: PCI: mvebu: Disable prefetchable memory support in PCI-to-PCI bridge" * tag 'pci-v3.11-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: PCI: mvebu: Disable prefetchable memory support in PCI-to-PCI bridge PCI: Retry allocation of only the resource type that failed PCI: pciehp: Convert pciehp to be builtin only, not modular PCI: hotplug: Convert to be builtin only, not modular PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device
This commit is contained in:
commit
aa8032b6fa
13 changed files with 87 additions and 44 deletions
|
@ -31,7 +31,7 @@ CONFIG_ACPI_FAN=m
|
|||
CONFIG_ACPI_DOCK=y
|
||||
CONFIG_ACPI_PROCESSOR=m
|
||||
CONFIG_ACPI_CONTAINER=m
|
||||
CONFIG_HOTPLUG_PCI=m
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_ACPI=m
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -25,7 +25,7 @@ CONFIG_ACPI_BUTTON=m
|
|||
CONFIG_ACPI_FAN=m
|
||||
CONFIG_ACPI_PROCESSOR=m
|
||||
CONFIG_ACPI_CONTAINER=m
|
||||
CONFIG_HOTPLUG_PCI=m
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_ACPI=m
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -31,7 +31,7 @@ CONFIG_ACPI_BUTTON=m
|
|||
CONFIG_ACPI_FAN=m
|
||||
CONFIG_ACPI_PROCESSOR=m
|
||||
CONFIG_ACPI_CONTAINER=m
|
||||
CONFIG_HOTPLUG_PCI=m
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_ACPI=m
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -32,7 +32,7 @@ CONFIG_ACPI_BUTTON=m
|
|||
CONFIG_ACPI_FAN=m
|
||||
CONFIG_ACPI_PROCESSOR=m
|
||||
CONFIG_ACPI_CONTAINER=m
|
||||
CONFIG_HOTPLUG_PCI=m
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_ACPI=m
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -58,7 +58,7 @@ CONFIG_SCHED_SMT=y
|
|||
CONFIG_PPC_DENORMALISATION=y
|
||||
CONFIG_PCCARD=y
|
||||
CONFIG_ELECTRA_CF=y
|
||||
CONFIG_HOTPLUG_PCI=m
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_RPA=m
|
||||
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -32,7 +32,7 @@ CONFIG_IRQ_ALL_CPUS=y
|
|||
CONFIG_SPARSEMEM_MANUAL=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCCARD=y
|
||||
CONFIG_HOTPLUG_PCI=m
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=m
|
||||
|
|
|
@ -53,7 +53,7 @@ CONFIG_PPC_64K_PAGES=y
|
|||
CONFIG_PPC_SUBPAGE_PROT=y
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_PPC_DENORMALISATION=y
|
||||
CONFIG_HOTPLUG_PCI=m
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_RPA=m
|
||||
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -22,7 +22,7 @@ CONFIG_PREEMPT=y
|
|||
CONFIG_CMDLINE_OVERWRITE=y
|
||||
CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
|
||||
CONFIG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI=m
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_BINFMT_MISC=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -86,10 +86,6 @@ struct mvebu_sw_pci_bridge {
|
|||
u16 secondary_status;
|
||||
u16 membase;
|
||||
u16 memlimit;
|
||||
u16 prefmembase;
|
||||
u16 prefmemlimit;
|
||||
u32 prefbaseupper;
|
||||
u32 preflimitupper;
|
||||
u16 iobaseupper;
|
||||
u16 iolimitupper;
|
||||
u8 cappointer;
|
||||
|
@ -419,15 +415,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
|
|||
break;
|
||||
|
||||
case PCI_PREF_MEMORY_BASE:
|
||||
*value = (bridge->prefmemlimit << 16 | bridge->prefmembase);
|
||||
break;
|
||||
|
||||
case PCI_PREF_BASE_UPPER32:
|
||||
*value = bridge->prefbaseupper;
|
||||
break;
|
||||
|
||||
case PCI_PREF_LIMIT_UPPER32:
|
||||
*value = bridge->preflimitupper;
|
||||
*value = 0;
|
||||
break;
|
||||
|
||||
case PCI_IO_BASE_UPPER16:
|
||||
|
@ -501,19 +489,6 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,
|
|||
mvebu_pcie_handle_membase_change(port);
|
||||
break;
|
||||
|
||||
case PCI_PREF_MEMORY_BASE:
|
||||
bridge->prefmembase = value & 0xffff;
|
||||
bridge->prefmemlimit = value >> 16;
|
||||
break;
|
||||
|
||||
case PCI_PREF_BASE_UPPER32:
|
||||
bridge->prefbaseupper = value;
|
||||
break;
|
||||
|
||||
case PCI_PREF_LIMIT_UPPER32:
|
||||
bridge->preflimitupper = value;
|
||||
break;
|
||||
|
||||
case PCI_IO_BASE_UPPER16:
|
||||
bridge->iobaseupper = value & 0xffff;
|
||||
bridge->iolimitupper = value >> 16;
|
||||
|
|
|
@ -3,16 +3,13 @@
|
|||
#
|
||||
|
||||
menuconfig HOTPLUG_PCI
|
||||
tristate "Support for PCI Hotplug"
|
||||
bool "Support for PCI Hotplug"
|
||||
depends on PCI && SYSFS
|
||||
---help---
|
||||
Say Y here if you have a motherboard with a PCI Hotplug controller.
|
||||
This allows you to add and remove PCI cards while the machine is
|
||||
powered up and running.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pci_hotplug.
|
||||
|
||||
When in doubt, say N.
|
||||
|
||||
if HOTPLUG_PCI
|
||||
|
|
|
@ -92,7 +92,14 @@ int pciehp_unconfigure_device(struct slot *p_slot)
|
|||
if (ret)
|
||||
presence = 0;
|
||||
|
||||
list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
|
||||
/*
|
||||
* Stopping an SR-IOV PF device removes all the associated VFs,
|
||||
* which will update the bus->devices list and confuse the
|
||||
* iterator. Therefore, iterate in reverse so we remove the VFs
|
||||
* first, then the PF. We do the same in pci_stop_bus_device().
|
||||
*/
|
||||
list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
|
||||
bus_list) {
|
||||
pci_dev_get(dev);
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
|
||||
pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
|
||||
|
|
|
@ -14,15 +14,12 @@ config PCIEPORTBUS
|
|||
# Include service Kconfig here
|
||||
#
|
||||
config HOTPLUG_PCI_PCIE
|
||||
tristate "PCI Express Hotplug driver"
|
||||
bool "PCI Express Hotplug driver"
|
||||
depends on HOTPLUG_PCI && PCIEPORTBUS
|
||||
help
|
||||
Say Y here if you have a motherboard that supports PCI Express Native
|
||||
Hotplug
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pciehp.
|
||||
|
||||
When in doubt, say N.
|
||||
|
||||
source "drivers/pci/pcie/aer/Kconfig"
|
||||
|
|
|
@ -300,6 +300,47 @@ static void assign_requested_resources_sorted(struct list_head *head,
|
|||
}
|
||||
}
|
||||
|
||||
static unsigned long pci_fail_res_type_mask(struct list_head *fail_head)
|
||||
{
|
||||
struct pci_dev_resource *fail_res;
|
||||
unsigned long mask = 0;
|
||||
|
||||
/* check failed type */
|
||||
list_for_each_entry(fail_res, fail_head, list)
|
||||
mask |= fail_res->flags;
|
||||
|
||||
/*
|
||||
* one pref failed resource will set IORESOURCE_MEM,
|
||||
* as we can allocate pref in non-pref range.
|
||||
* Will release all assigned non-pref sibling resources
|
||||
* according to that bit.
|
||||
*/
|
||||
return mask & (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH);
|
||||
}
|
||||
|
||||
static bool pci_need_to_release(unsigned long mask, struct resource *res)
|
||||
{
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
return !!(mask & IORESOURCE_IO);
|
||||
|
||||
/* check pref at first */
|
||||
if (res->flags & IORESOURCE_PREFETCH) {
|
||||
if (mask & IORESOURCE_PREFETCH)
|
||||
return true;
|
||||
/* count pref if its parent is non-pref */
|
||||
else if ((mask & IORESOURCE_MEM) &&
|
||||
!(res->parent->flags & IORESOURCE_PREFETCH))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (res->flags & IORESOURCE_MEM)
|
||||
return !!(mask & IORESOURCE_MEM);
|
||||
|
||||
return false; /* should not get here */
|
||||
}
|
||||
|
||||
static void __assign_resources_sorted(struct list_head *head,
|
||||
struct list_head *realloc_head,
|
||||
struct list_head *fail_head)
|
||||
|
@ -312,11 +353,24 @@ static void __assign_resources_sorted(struct list_head *head,
|
|||
* if could do that, could get out early.
|
||||
* if could not do that, we still try to assign requested at first,
|
||||
* then try to reassign add_size for some resources.
|
||||
*
|
||||
* Separate three resource type checking if we need to release
|
||||
* assigned resource after requested + add_size try.
|
||||
* 1. if there is io port assign fail, will release assigned
|
||||
* io port.
|
||||
* 2. if there is pref mmio assign fail, release assigned
|
||||
* pref mmio.
|
||||
* if assigned pref mmio's parent is non-pref mmio and there
|
||||
* is non-pref mmio assign fail, will release that assigned
|
||||
* pref mmio.
|
||||
* 3. if there is non-pref mmio assign fail or pref mmio
|
||||
* assigned fail, will release assigned non-pref mmio.
|
||||
*/
|
||||
LIST_HEAD(save_head);
|
||||
LIST_HEAD(local_fail_head);
|
||||
struct pci_dev_resource *save_res;
|
||||
struct pci_dev_resource *dev_res;
|
||||
struct pci_dev_resource *dev_res, *tmp_res;
|
||||
unsigned long fail_type;
|
||||
|
||||
/* Check if optional add_size is there */
|
||||
if (!realloc_head || list_empty(realloc_head))
|
||||
|
@ -348,6 +402,19 @@ static void __assign_resources_sorted(struct list_head *head,
|
|||
return;
|
||||
}
|
||||
|
||||
/* check failed type */
|
||||
fail_type = pci_fail_res_type_mask(&local_fail_head);
|
||||
/* remove not need to be released assigned res from head list etc */
|
||||
list_for_each_entry_safe(dev_res, tmp_res, head, list)
|
||||
if (dev_res->res->parent &&
|
||||
!pci_need_to_release(fail_type, dev_res->res)) {
|
||||
/* remove it from realloc_head list */
|
||||
remove_from_list(realloc_head, dev_res->res);
|
||||
remove_from_list(&save_head, dev_res->res);
|
||||
list_del(&dev_res->list);
|
||||
kfree(dev_res);
|
||||
}
|
||||
|
||||
free_list(&local_fail_head);
|
||||
/* Release assigned resource */
|
||||
list_for_each_entry(dev_res, head, list)
|
||||
|
|
Loading…
Reference in a new issue