提交 e3dffa4f 编写于 作者: J Jon Derrick 提交者: Lorenzo Pieralisi

PCI: vmd: Fix config addressing when using bus offsets

VMD maps child device config spaces to the VMD Config BAR linearly
regardless of the starting bus offset. Because of this, the config
address decode must ignore starting bus offsets when mapping the BDF to
the config space address.

Fixes: 2a5a9c9a ("PCI: vmd: Add offset to bus numbers if necessary")
Signed-off-by: NJon Derrick <jonathan.derrick@intel.com>
Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: stable@vger.kernel.org # v5.2+
上级 5f9e832c
...@@ -94,6 +94,7 @@ struct vmd_dev { ...@@ -94,6 +94,7 @@ struct vmd_dev {
struct resource resources[3]; struct resource resources[3];
struct irq_domain *irq_domain; struct irq_domain *irq_domain;
struct pci_bus *bus; struct pci_bus *bus;
u8 busn_start;
struct dma_map_ops dma_ops; struct dma_map_ops dma_ops;
struct dma_domain dma_domain; struct dma_domain dma_domain;
...@@ -440,7 +441,8 @@ static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus, ...@@ -440,7 +441,8 @@ static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus,
unsigned int devfn, int reg, int len) unsigned int devfn, int reg, int len)
{ {
char __iomem *addr = vmd->cfgbar + char __iomem *addr = vmd->cfgbar +
(bus->number << 20) + (devfn << 12) + reg; ((bus->number - vmd->busn_start) << 20) +
(devfn << 12) + reg;
if ((addr - vmd->cfgbar) + len >= if ((addr - vmd->cfgbar) + len >=
resource_size(&vmd->dev->resource[VMD_CFGBAR])) resource_size(&vmd->dev->resource[VMD_CFGBAR]))
...@@ -563,7 +565,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) ...@@ -563,7 +565,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
unsigned long flags; unsigned long flags;
LIST_HEAD(resources); LIST_HEAD(resources);
resource_size_t offset[2] = {0}; resource_size_t offset[2] = {0};
resource_size_t membar2_offset = 0x2000, busn_start = 0; resource_size_t membar2_offset = 0x2000;
struct pci_bus *child; struct pci_bus *child;
/* /*
...@@ -606,14 +608,14 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) ...@@ -606,14 +608,14 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
pci_read_config_dword(vmd->dev, PCI_REG_VMCONFIG, &vmconfig); pci_read_config_dword(vmd->dev, PCI_REG_VMCONFIG, &vmconfig);
if (BUS_RESTRICT_CAP(vmcap) && if (BUS_RESTRICT_CAP(vmcap) &&
(BUS_RESTRICT_CFG(vmconfig) == 0x1)) (BUS_RESTRICT_CFG(vmconfig) == 0x1))
busn_start = 128; vmd->busn_start = 128;
} }
res = &vmd->dev->resource[VMD_CFGBAR]; res = &vmd->dev->resource[VMD_CFGBAR];
vmd->resources[0] = (struct resource) { vmd->resources[0] = (struct resource) {
.name = "VMD CFGBAR", .name = "VMD CFGBAR",
.start = busn_start, .start = vmd->busn_start,
.end = busn_start + (resource_size(res) >> 20) - 1, .end = vmd->busn_start + (resource_size(res) >> 20) - 1,
.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED, .flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED,
}; };
...@@ -681,8 +683,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) ...@@ -681,8 +683,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]); pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]);
pci_add_resource_offset(&resources, &vmd->resources[2], offset[1]); pci_add_resource_offset(&resources, &vmd->resources[2], offset[1]);
vmd->bus = pci_create_root_bus(&vmd->dev->dev, busn_start, &vmd_ops, vmd->bus = pci_create_root_bus(&vmd->dev->dev, vmd->busn_start,
sd, &resources); &vmd_ops, sd, &resources);
if (!vmd->bus) { if (!vmd->bus) {
pci_free_resource_list(&resources); pci_free_resource_list(&resources);
irq_domain_remove(vmd->irq_domain); irq_domain_remove(vmd->irq_domain);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册