diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 4c28f1e4e2..0167731ab0 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -747,6 +747,22 @@ static int __init write_properties(struct domain *d, struct kernel_info *kinfo, return res; } + if ( is_pci_passthrough_enabled() && dt_device_type_is_equal(node, "pci") ) + { + if ( !dt_find_property(node, "linux,pci-domain", NULL) ) + { + uint16_t segment; + + res = pci_get_host_bridge_segment(node, &segment); + if ( res < 0 ) + return res; + + res = fdt_property_cell(kinfo->fdt, "linux,pci-domain", segment); + if ( res ) + return res; + } + } + /* * Override the property "status" to disable the device when it's * marked for passthrough. diff --git a/xen/arch/arm/pci/pci-host-common.c b/xen/arch/arm/pci/pci-host-common.c index af208e7298..cdeb3a283a 100644 --- a/xen/arch/arm/pci/pci-host-common.c +++ b/xen/arch/arm/pci/pci-host-common.c @@ -271,6 +271,27 @@ struct pci_host_bridge *pci_find_host_bridge(uint16_t segment, uint8_t bus) return NULL; } + +/* + * This function will lookup an hostbridge based on config space address. + */ +int pci_get_host_bridge_segment(const struct dt_device_node *node, + uint16_t *segment) +{ + struct pci_host_bridge *bridge; + + list_for_each_entry( bridge, &pci_host_bridges, node ) + { + if ( bridge->dt_node != node ) + continue; + + *segment = bridge->segment; + return 0; + } + + return -EINVAL; +} + /* * Local variables: * mode: C diff --git a/xen/include/asm-arm/pci.h b/xen/include/asm-arm/pci.h index aa0762ff15..81273e0d87 100644 --- a/xen/include/asm-arm/pci.h +++ b/xen/include/asm-arm/pci.h @@ -98,6 +98,8 @@ void __iomem *pci_ecam_map_bus(struct pci_host_bridge *bridge, pci_sbdf_t sbdf, uint32_t where); struct pci_host_bridge *pci_find_host_bridge(uint16_t segment, uint8_t bus); struct dt_device_node *pci_find_host_bridge_node(struct device *dev); +int pci_get_host_bridge_segment(const struct dt_device_node *node, + uint16_t *segment); static always_inline bool is_pci_passthrough_enabled(void) { @@ -119,5 +121,12 @@ struct pci_dev; static inline void arch_pci_init_pdev(struct pci_dev *pdev) {} +static inline int pci_get_host_bridge_segment(const struct dt_device_node *node, + uint16_t *segment) +{ + ASSERT_UNREACHABLE(); + return -EINVAL; +} + #endif /*!CONFIG_HAS_PCI*/ #endif /* __ARM_PCI_H__ */