Set the vPCI flag in xen_domctl_createdomain to enable vPCI for dom0 if
iommu and PCI passthrough are enabled and there exists a PCI host bridge
in the system.
Adjust pci_host_iterate_bridges_and_count() to count the number of host
bridges if no callback is provided.
Signed-off-by: Stewart Hildebrand <stewart.hildebrand@amd.com>
---
Allowing/enabling vPCI for dom0 on ARM should follow or be part of the
PCI passthrough SMMU series [1]. I'm including it here due to
prerequisites in this Kconfig series. Once the prerequisites are
committed I'll move this patch to the PCI passthrough SMMU series.
v5->v6:
* no change
v4->v5:
* add [FUTURE] tag
* move flags_optional change from the previous patch to here
v3->v4:
* depend on iommu_enabled, pci_passthrough_enabled, and whether there
is a pci host bridge
v2->v3:
* new patch
[1] https://lists.xenproject.org/archives/html/xen-devel/2023-10/msg00210.html
---
xen/arch/arm/domain.c | 3 ++-
xen/arch/arm/domain_build.c | 6 ++++++
xen/arch/arm/include/asm/pci.h | 9 +++++++++
xen/arch/arm/pci/pci-host-common.c | 11 ++++++++---
4 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 28e3aaa5e482..1409a4235e13 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -607,7 +607,8 @@ int arch_sanitise_domain_config(struct xen_domctl_createdomain *config)
{
unsigned int max_vcpus;
unsigned int flags_required = (XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap);
- unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_vpmu);
+ unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_vpmu |
+ XEN_DOMCTL_CDF_vpci);
unsigned int sve_vl_bits = sve_decode_vl(config->arch.sve_vl);
if ( (config->flags & ~flags_optional) != flags_required )
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 2dd2926b4144..512b3c4c76e2 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -3916,6 +3916,12 @@ void __init create_dom0(void)
panic("SVE vector length error\n");
}
+ if ( IS_ENABLED(CONFIG_HAS_VPCI) &&
+ iommu_enabled &&
+ is_pci_passthrough_enabled() &&
+ (pci_host_iterate_bridges_and_count(NULL, NULL) > 0) )
+ dom0_cfg.flags |= XEN_DOMCTL_CDF_vpci;
+
dom0 = domain_create(0, &dom0_cfg, CDF_privileged | CDF_directmap);
if ( IS_ERR(dom0) )
panic("Error creating domain 0 (rc = %ld)\n", PTR_ERR(dom0));
diff --git a/xen/arch/arm/include/asm/pci.h b/xen/arch/arm/include/asm/pci.h
index 7f77226c9bbf..74816a687bbb 100644
--- a/xen/arch/arm/include/asm/pci.h
+++ b/xen/arch/arm/include/asm/pci.h
@@ -147,5 +147,14 @@ static inline int pci_get_new_domain_nr(void)
return -1;
}
+struct pci_host_bridge;
+
+static inline int pci_host_iterate_bridges_and_count(
+ struct domain *d,
+ int (*cb)(struct domain *d, struct pci_host_bridge *bridge))
+{
+ return 0;
+}
+
#endif /*!CONFIG_HAS_PCI*/
#endif /* __ARM_PCI_H__ */
diff --git a/xen/arch/arm/pci/pci-host-common.c b/xen/arch/arm/pci/pci-host-common.c
index c0faf0f43675..e6a03ae668f8 100644
--- a/xen/arch/arm/pci/pci-host-common.c
+++ b/xen/arch/arm/pci/pci-host-common.c
@@ -319,9 +319,14 @@ int pci_host_iterate_bridges_and_count(struct domain *d,
{
int ret;
- ret = cb(d, bridge);
- if ( ret < 0 )
- return ret;
+ if ( cb )
+ {
+ ret = cb(d, bridge);
+ if ( ret < 0 )
+ return ret;
+ }
+ else
+ ret = 1;
count += ret;
}
return count;
--
2.42.0