summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Derrick <jonathan.derrick@intel.com>2020-05-27 23:02:39 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-06-24 17:50:17 +0200
commit3851967ff5678f4321ee75dbbbad1a5a3305e912 (patch)
tree9f70db92a1ce6a15d04f362702cb62dc39d74a46
parente8cac2e3067e8587f8271c2177cc5ca924a61b54 (diff)
PCI: vmd: Filter resource type bits from shadow register
[ Upstream commit 3e5095eebe015d5a4d566aa5e03c8621add5f0a7 ] Versions of VMD with the Host Physical Address shadow register use this register to calculate the bus address offset needed to do guest passthrough of the domain. This register shadows the Host Physical Address registers including the resource type bits. After calculating the offset, the extra resource type bits lead to the VMD resources being over-provisioned at the front and under-provisioned at the back. Example: pci 10000:80:02.0: reg 0x10: [mem 0xf801fffc-0xf803fffb 64bit] Expected: pci 10000:80:02.0: reg 0x10: [mem 0xf8020000-0xf803ffff 64bit] If other devices are mapped in the over-provisioned front, it could lead to resource conflict issues with VMD or those devices. Link: https://lore.kernel.org/r/20200528030240.16024-3-jonathan.derrick@intel.com Fixes: a1a30170138c9 ("PCI: vmd: Fix shadow offsets to reflect spec changes") Signed-off-by: Jon Derrick <jonathan.derrick@intel.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/pci/controller/vmd.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index afc1a3d240b5..87348ecfe3fc 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -593,9 +593,11 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
if (!membar2)
return -ENOMEM;
offset[0] = vmd->dev->resource[VMD_MEMBAR1].start -
- readq(membar2 + MB2_SHADOW_OFFSET);
+ (readq(membar2 + MB2_SHADOW_OFFSET) &
+ PCI_BASE_ADDRESS_MEM_MASK);
offset[1] = vmd->dev->resource[VMD_MEMBAR2].start -
- readq(membar2 + MB2_SHADOW_OFFSET + 8);
+ (readq(membar2 + MB2_SHADOW_OFFSET + 8) &
+ PCI_BASE_ADDRESS_MEM_MASK);
pci_iounmap(vmd->dev, membar2);
}
}