From f0b99f70e92dcdc4fecf5cf7ce2f6857ddd82c65 Mon Sep 17 00:00:00 2001 From: Yongji Xie Date: Tue, 13 Sep 2016 17:00:31 +0800 Subject: PCI: Ignore requested alignment for PROBE_ONLY and fixed resources Users may request additional alignment of PCI resources, e.g., to align BARs on page boundaries so they can be shared with guests via VFIO. This of course may require reallocation if firmware has already assigned the BARs with smaller alignments. If the platform has requested PCI_PROBE_ONLY, we should never change any PCI BARs, so we can't provide any additional alignment. Also, if a BAR is marked as IORESOURCE_PCI_FIXED, e.g., for PCI Enhanced Allocation or if the firmware depends on the current BAR value, we can't change the alignment. In these cases, log a message and ignore the user's alignment requests. [bhelgaas: changelog, use goto to simplify PCI_PROBE_ONLY check] Signed-off-by: Yongji Xie Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index aab9d5115a5f..ed9447aee863 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4959,6 +4959,13 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) spin_lock(&resource_alignment_lock); p = resource_alignment_param; + if (!*p) + goto out; + if (pci_has_flag(PCI_PROBE_ONLY)) { + pr_info_once("PCI: Ignoring requested alignments (PCI_PROBE_ONLY)\n"); + goto out; + } + while (*p) { count = 0; if (sscanf(p, "%d%n", &align_order, &count) == 1 && @@ -5023,6 +5030,7 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) } p++; } +out: spin_unlock(&resource_alignment_lock); return align; } @@ -5063,6 +5071,12 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) r = &dev->resource[i]; if (!(r->flags & IORESOURCE_MEM)) continue; + if (r->flags & IORESOURCE_PCI_FIXED) { + dev_info(&dev->dev, "Ignoring requested alignment for BAR%d: %pR\n", + i, r); + continue; + } + size = resource_size(r); if (size < align) { size = align; -- cgit v1.2.3 From 62d9a78f32d9a1b0f6fdae70751deeae6335e74b Mon Sep 17 00:00:00 2001 From: Yongji Xie Date: Tue, 13 Sep 2016 17:00:32 +0800 Subject: PCI: Ignore requested alignment for VF BARs Resource allocation for VFs is done via the VF BARx registers in the PF's SR-IOV Capability, and the BARs in the VFs themselves are read-only zeros (see SR-IOV spec r1.1, secs 3.3.14 and 3.4.1.11). Even though the actual VF BARs are read-only zeros, the VF dev->resource[] structs describe the space allocated for the VF (this is a piece of the space described by the VF BARx register in the PF's SR-IOV capability). It's meaningless to request additional alignment for a VF: the VF BAR alignment is completely determined by the alignment of the VF BARx in the PF and the size of the VF BAR. Ignore the user's alignment requests for VF devices. Signed-off-by: Yongji Xie Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ed9447aee863..b5b83331da26 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5049,6 +5049,15 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) resource_size_t align, size; u16 command; + /* + * VF BARs are read-only zero according to SR-IOV spec r1.1, sec + * 3.4.1.11. Their resources are allocated from the space + * described by the VF BARx register in the PF's SR-IOV capability. + * We can't influence their alignment here. + */ + if (dev->is_virtfn) + return; + /* check if specified PCI is target device to reassign */ align = pci_specified_resource_alignment(dev); if (!align) -- cgit v1.2.3