Commit aa8032b6 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 1fe0135b 36dd1f3e
...@@ -31,7 +31,7 @@ CONFIG_ACPI_FAN=m ...@@ -31,7 +31,7 @@ CONFIG_ACPI_FAN=m
CONFIG_ACPI_DOCK=y CONFIG_ACPI_DOCK=y
CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_CONTAINER=m CONFIG_ACPI_CONTAINER=m
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=m CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_PACKET=y CONFIG_PACKET=y
CONFIG_UNIX=y CONFIG_UNIX=y
......
...@@ -25,7 +25,7 @@ CONFIG_ACPI_BUTTON=m ...@@ -25,7 +25,7 @@ CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_CONTAINER=m CONFIG_ACPI_CONTAINER=m
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=m CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_PACKET=y CONFIG_PACKET=y
CONFIG_UNIX=y CONFIG_UNIX=y
......
...@@ -31,7 +31,7 @@ CONFIG_ACPI_BUTTON=m ...@@ -31,7 +31,7 @@ CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_CONTAINER=m CONFIG_ACPI_CONTAINER=m
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=m CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_PACKET=y CONFIG_PACKET=y
CONFIG_UNIX=y CONFIG_UNIX=y
......
...@@ -32,7 +32,7 @@ CONFIG_ACPI_BUTTON=m ...@@ -32,7 +32,7 @@ CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_CONTAINER=m CONFIG_ACPI_CONTAINER=m
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=m CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_PACKET=y CONFIG_PACKET=y
CONFIG_UNIX=y CONFIG_UNIX=y
......
...@@ -58,7 +58,7 @@ CONFIG_SCHED_SMT=y ...@@ -58,7 +58,7 @@ CONFIG_SCHED_SMT=y
CONFIG_PPC_DENORMALISATION=y CONFIG_PPC_DENORMALISATION=y
CONFIG_PCCARD=y CONFIG_PCCARD=y
CONFIG_ELECTRA_CF=y CONFIG_ELECTRA_CF=y
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_RPA=m CONFIG_HOTPLUG_PCI_RPA=m
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
CONFIG_PACKET=y CONFIG_PACKET=y
......
...@@ -32,7 +32,7 @@ CONFIG_IRQ_ALL_CPUS=y ...@@ -32,7 +32,7 @@ CONFIG_IRQ_ALL_CPUS=y
CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM_MANUAL=y
CONFIG_PCI_MSI=y CONFIG_PCI_MSI=y
CONFIG_PCCARD=y CONFIG_PCCARD=y
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=y
CONFIG_PACKET=y CONFIG_PACKET=y
CONFIG_UNIX=y CONFIG_UNIX=y
CONFIG_XFRM_USER=m CONFIG_XFRM_USER=m
......
...@@ -53,7 +53,7 @@ CONFIG_PPC_64K_PAGES=y ...@@ -53,7 +53,7 @@ CONFIG_PPC_64K_PAGES=y
CONFIG_PPC_SUBPAGE_PROT=y CONFIG_PPC_SUBPAGE_PROT=y
CONFIG_SCHED_SMT=y CONFIG_SCHED_SMT=y
CONFIG_PPC_DENORMALISATION=y CONFIG_PPC_DENORMALISATION=y
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_RPA=m CONFIG_HOTPLUG_PCI_RPA=m
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
CONFIG_PACKET=y CONFIG_PACKET=y
......
...@@ -22,7 +22,7 @@ CONFIG_PREEMPT=y ...@@ -22,7 +22,7 @@ CONFIG_PREEMPT=y
CONFIG_CMDLINE_OVERWRITE=y CONFIG_CMDLINE_OVERWRITE=y
CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs" CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=y
CONFIG_BINFMT_MISC=y CONFIG_BINFMT_MISC=y
CONFIG_NET=y CONFIG_NET=y
CONFIG_PACKET=y CONFIG_PACKET=y
......
...@@ -86,10 +86,6 @@ struct mvebu_sw_pci_bridge { ...@@ -86,10 +86,6 @@ struct mvebu_sw_pci_bridge {
u16 secondary_status; u16 secondary_status;
u16 membase; u16 membase;
u16 memlimit; u16 memlimit;
u16 prefmembase;
u16 prefmemlimit;
u32 prefbaseupper;
u32 preflimitupper;
u16 iobaseupper; u16 iobaseupper;
u16 iolimitupper; u16 iolimitupper;
u8 cappointer; u8 cappointer;
...@@ -419,15 +415,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, ...@@ -419,15 +415,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
break; break;
case PCI_PREF_MEMORY_BASE: case PCI_PREF_MEMORY_BASE:
*value = (bridge->prefmemlimit << 16 | bridge->prefmembase); *value = 0;
break;
case PCI_PREF_BASE_UPPER32:
*value = bridge->prefbaseupper;
break;
case PCI_PREF_LIMIT_UPPER32:
*value = bridge->preflimitupper;
break; break;
case PCI_IO_BASE_UPPER16: case PCI_IO_BASE_UPPER16:
...@@ -501,19 +489,6 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, ...@@ -501,19 +489,6 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,
mvebu_pcie_handle_membase_change(port); mvebu_pcie_handle_membase_change(port);
break; 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: case PCI_IO_BASE_UPPER16:
bridge->iobaseupper = value & 0xffff; bridge->iobaseupper = value & 0xffff;
bridge->iolimitupper = value >> 16; bridge->iolimitupper = value >> 16;
......
...@@ -3,16 +3,13 @@ ...@@ -3,16 +3,13 @@
# #
menuconfig HOTPLUG_PCI menuconfig HOTPLUG_PCI
tristate "Support for PCI Hotplug" bool "Support for PCI Hotplug"
depends on PCI && SYSFS depends on PCI && SYSFS
---help--- ---help---
Say Y here if you have a motherboard with a PCI Hotplug controller. 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 This allows you to add and remove PCI cards while the machine is
powered up and running. 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. When in doubt, say N.
if HOTPLUG_PCI if HOTPLUG_PCI
......
...@@ -92,7 +92,14 @@ int pciehp_unconfigure_device(struct slot *p_slot) ...@@ -92,7 +92,14 @@ int pciehp_unconfigure_device(struct slot *p_slot)
if (ret) if (ret)
presence = 0; 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); pci_dev_get(dev);
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
......
...@@ -14,15 +14,12 @@ config PCIEPORTBUS ...@@ -14,15 +14,12 @@ config PCIEPORTBUS
# Include service Kconfig here # Include service Kconfig here
# #
config HOTPLUG_PCI_PCIE config HOTPLUG_PCI_PCIE
tristate "PCI Express Hotplug driver" bool "PCI Express Hotplug driver"
depends on HOTPLUG_PCI && PCIEPORTBUS depends on HOTPLUG_PCI && PCIEPORTBUS
help help
Say Y here if you have a motherboard that supports PCI Express Native Say Y here if you have a motherboard that supports PCI Express Native
Hotplug Hotplug
To compile this driver as a module, choose M here: the
module will be called pciehp.
When in doubt, say N. When in doubt, say N.
source "drivers/pci/pcie/aer/Kconfig" source "drivers/pci/pcie/aer/Kconfig"
......
...@@ -300,6 +300,47 @@ static void assign_requested_resources_sorted(struct list_head *head, ...@@ -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, static void __assign_resources_sorted(struct list_head *head,
struct list_head *realloc_head, struct list_head *realloc_head,
struct list_head *fail_head) struct list_head *fail_head)
...@@ -312,11 +353,24 @@ static void __assign_resources_sorted(struct list_head *head, ...@@ -312,11 +353,24 @@ static void __assign_resources_sorted(struct list_head *head,
* if could do that, could get out early. * if could do that, could get out early.
* if could not do that, we still try to assign requested at first, * if could not do that, we still try to assign requested at first,
* then try to reassign add_size for some resources. * 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(save_head);
LIST_HEAD(local_fail_head); LIST_HEAD(local_fail_head);
struct pci_dev_resource *save_res; 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 */ /* Check if optional add_size is there */
if (!realloc_head || list_empty(realloc_head)) if (!realloc_head || list_empty(realloc_head))
...@@ -348,6 +402,19 @@ static void __assign_resources_sorted(struct list_head *head, ...@@ -348,6 +402,19 @@ static void __assign_resources_sorted(struct list_head *head,
return; 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); free_list(&local_fail_head);
/* Release assigned resource */ /* Release assigned resource */
list_for_each_entry(dev_res, head, list) list_for_each_entry(dev_res, head, list)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment