Merge branch 'x86/kprobes' of git://git.kernel.org/pub/scm/linux/kernel/git/frob...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 18 Jul 2010 22:13:30 +0000 (15:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 18 Jul 2010 22:13:30 +0000 (15:13 -0700)
* 'x86/kprobes' of git://git.kernel.org/pub/scm/linux/kernel/git/frob/linux-2.6-roland:
  x86: kprobes: fix swapped segment registers in kretprobe

arch/x86/pci/i386.c
drivers/pci/setup-res.c
include/linux/pci.h

index 6fdb3ec..5525309 100644 (file)
@@ -184,6 +184,7 @@ static void __init pcibios_allocate_resources(int pass)
                                        idx, r, disabled, pass);
                                if (pci_claim_resource(dev, idx) < 0) {
                                        /* We'll assign a new address later */
+                                       dev->fw_addr[idx] = r->start;
                                        r->end -= r->start;
                                        r->start = 0;
                                }
index 92379e2..2aaa131 100644 (file)
@@ -156,6 +156,38 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
                                             pcibios_align_resource, dev);
        }
 
+       if (ret < 0 && dev->fw_addr[resno]) {
+               struct resource *root, *conflict;
+               resource_size_t start, end;
+
+               /*
+                * If we failed to assign anything, let's try the address
+                * where firmware left it.  That at least has a chance of
+                * working, which is better than just leaving it disabled.
+                */
+
+               if (res->flags & IORESOURCE_IO)
+                       root = &ioport_resource;
+               else
+                       root = &iomem_resource;
+
+               start = res->start;
+               end = res->end;
+               res->start = dev->fw_addr[resno];
+               res->end = res->start + size - 1;
+               dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n",
+                        resno, res);
+               conflict = request_resource_conflict(root, res);
+               if (conflict) {
+                       dev_info(&dev->dev,
+                                "BAR %d: %pR conflicts with %s %pR\n", resno,
+                                res, conflict->name, conflict);
+                       res->start = start;
+                       res->end = end;
+               } else
+                       ret = 0;
+       }
+
        if (!ret) {
                res->flags &= ~IORESOURCE_STARTALIGN;
                dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
index 7cb0084..f26fda7 100644 (file)
@@ -288,6 +288,7 @@ struct pci_dev {
         */
        unsigned int    irq;
        struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
+       resource_size_t fw_addr[DEVICE_COUNT_RESOURCE]; /* FW-assigned addr */
 
        /* These fields are used by common fixups */
        unsigned int    transparent:1;  /* Transparent PCI bridge */