summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/controller/vmd.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 76a45b48d09f..9b283e151c1a 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -917,6 +917,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
resource_size_t busn_end;
struct pci_bus *child;
struct pci_dev *dev;
+ bool vmd_in_guest;
int ret;
ret = vmd_prepare_offsets_and_bus(vmd, features, &membar2_offset,
@@ -978,14 +979,16 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
.parent = res,
};
+ /* Non-zero offset means guest/direct assign view. */
+ vmd_in_guest = offset[0] || offset[1];
+
/*
* Currently MSI remapping must be enabled in guest passthrough mode
* due to some missing interrupt remapping plumbing. This is probably
* acceptable because the guest is usually CPU-limited and MSI
* remapping doesn't become a performance bottleneck.
*/
- if (!(features & VMD_FEAT_CAN_BYPASS_MSI_REMAP) ||
- offset[0] || offset[1]) {
+ if (!(features & VMD_FEAT_CAN_BYPASS_MSI_REMAP) || vmd_in_guest) {
ret = vmd_alloc_irqs(vmd);
if (ret)
return ret;
@@ -1026,8 +1029,13 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
return -ENODEV;
}
- vmd_copy_host_bridge_flags(pci_find_host_bridge(vmd->dev->bus),
- to_pci_host_bridge(vmd->bus->bridge));
+ /*
+ * Don't copy _OSC control flags from root bridge if running in a VM, as
+ * they don't reflect the physical root bridge capabilities.
+ */
+ if (!vmd_in_guest)
+ vmd_copy_host_bridge_flags(pci_find_host_bridge(vmd->dev->bus),
+ to_pci_host_bridge(vmd->bus->bridge));
vmd_attach_resources(vmd);
if (vmd->irq_domain)