summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorJon Derrick <jonathan.derrick@intel.com>2020-05-28 06:02:39 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-06-25 16:32:51 +0300
commit8861d95c653c4150ad92505e7d287ba23bf69d15 (patch)
tree0235a92e81aa41e52e0a9a9cf03af3df1d334e1e /drivers/pci
parent22c721560ef24003bcb9c3d9c358841dcfa4e212 (diff)
downloadlinux-8861d95c653c4150ad92505e7d287ba23bf69d15.tar.xz
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>
Diffstat (limited to 'drivers/pci')
-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 b52885020c85..c3ac7f094a39 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -617,9 +617,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);
}
}