PCI: vmd: Only copy root bridge _OSC control flags in bare metal OS

Only in a bare metal OS environment, the _OSC control flags like Hotplug,
PME, AER, etc. reflect the physical root bridge capabilities. But in a VM
environment, these flags reflect the hypervisor policy and in most cases,
the hypervisor disables all of these control flags to the guest.

So copying these flags would needlessly disable these features in the VMD
owned Root Ports. Hence, copy the flags only when VMD is running in a bare
metal OS environment.

Signed-off-by: Nirmal Patel <nirmal.patel@linux.intel.com>
[mani: commit log and comment rewording]
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Link: https://patch.msgid.link/20260713220844.561357-1-nirmal.patel@intel.com
This commit is contained in:
Nirmal Patel 2026-07-13 22:08:44 +00:00 committed by Manivannan Sadhasivam
parent 72b32eccbc
commit 2162572d34

View File

@ -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)