diff options
| -rw-r--r-- | drivers/pci/controller/vmd.c | 16 |
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) |
