4 * (resno - PCI_IOV_RESOURCES);
 }
 
+/**
+ * pci_sriov_resource_alignment - get resource alignment for VF BAR
+ * @dev: the PCI device
+ * @resno: the resource number
+ *
+ * Returns the alignment of the VF BAR found in the SR-IOV capability.
+ * This is not the same as the resource size which is defined as
+ * the VF BAR size multiplied by the number of VFs.  The alignment
+ * is just the VF BAR size.
+ */
+int pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
+{
+       struct resource tmp;
+       enum pci_bar_type type;
+       int reg = pci_iov_resource_bar(dev, resno, &type);
+       
+       if (!reg)
+               return 0;
+
+        __pci_read_base(dev, type, &tmp, reg);
+       return resource_alignment(&tmp);
+}
+
 /**
  * pci_restore_iov_state - restore the state of the IOV capability
  * @dev: the PCI device
 
 extern void pci_iov_release(struct pci_dev *dev);
 extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
                                enum pci_bar_type *type);
+extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
 extern void pci_restore_iov_state(struct pci_dev *dev);
 extern int pci_iov_bus_range(struct pci_bus *bus);
 
 }
 #endif /* CONFIG_PCI_IOV */
 
+static inline int pci_resource_alignment(struct pci_dev *dev,
+                                        struct resource *res)
+{
+#ifdef CONFIG_PCI_IOV
+       int resno = res - dev->resource;
+
+       if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
+               return pci_sriov_resource_alignment(dev, resno);
+#endif
+       return resource_alignment(res);
+}
+
 #endif /* DRIVERS_PCI_H */
 
 #include <linux/ioport.h>
 #include <linux/cache.h>
 #include <linux/slab.h>
-
+#include "pci.h"
 
 static void pbus_assign_resources_sorted(const struct pci_bus *bus)
 {
                                continue;
                        r_size = resource_size(r);
                        /* For bridges size != alignment */
-                       align = resource_alignment(r);
+                       align = pci_resource_alignment(dev, r);
                        order = __ffs(align) - 20;
                        if (order > 11) {
                                dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
 
 
        size = resource_size(res);
        min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
-       align = resource_alignment(res);
+       align = pci_resource_alignment(dev, res);
 
        /* First, try exact prefetching match.. */
        ret = pci_bus_alloc_resource(bus, res, size, align, min,
        struct pci_bus *bus;
        int ret;
 
-       align = resource_alignment(res);
+       align = pci_resource_alignment(dev, res);
        if (!align) {
                dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
                        "alignment) %pR flags %#lx\n",
                if (!(r->flags) || r->parent)
                        continue;
 
-               r_align = resource_alignment(r);
+               r_align = pci_resource_alignment(dev, r);
                if (!r_align) {
                        dev_warn(&dev->dev, "BAR %d: bogus alignment "
                                "%pR flags %#lx\n",
                        struct resource_list *ln = list->next;
 
                        if (ln)
-                               align = resource_alignment(ln->res);
+                               align = pci_resource_alignment(ln->dev, ln->res);
 
                        if (r_align > align) {
                                tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);