[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 7/8] xen/pci: assign discovered devices to hwdom
From: Luca Fancellu <luca.fancellu@xxxxxxx> Hook up existing PCI setup routines for hwdom into Arm iommu initialization sequence, only assign endpoint devices. During scanned PCI device assignment, also permit access to the BAR ranges if hwdom is using vpci. Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx> Signed-off-by: Luca Fancellu <luca.fancellu@xxxxxxx> Signed-off-by: Mykyta Poturai <mykyta_poturai@xxxxxxxx> --- xen/drivers/passthrough/arm/iommu.c | 9 +++++++ xen/drivers/passthrough/pci.c | 40 ++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c index 100545e23f..d110520e0d 100644 --- a/xen/drivers/passthrough/arm/iommu.c +++ b/xen/drivers/passthrough/arm/iommu.c @@ -19,6 +19,7 @@ #include <xen/device_tree.h> #include <xen/iommu.h> #include <xen/lib.h> +#include <xen/sched.h> #include <asm/device.h> @@ -133,6 +134,12 @@ void arch_iommu_domain_destroy(struct domain *d) { } +static int iommu_add_hwdom_pci_device(u8 devfn, struct pci_dev *pdev) +{ + const struct domain_iommu *hd = dom_iommu(hardware_domain); + return iommu_call(hd->platform_ops, add_device, devfn, pci_to_dev(pdev)); +} + void __hwdom_init arch_iommu_hwdom_init(struct domain *d) { /* Set to false options not supported on ARM. */ @@ -142,6 +149,8 @@ void __hwdom_init arch_iommu_hwdom_init(struct domain *d) if ( iommu_hwdom_reserved == 1 ) printk(XENLOG_WARNING "map-reserved dom0-iommu option is not supported on ARM\n"); iommu_hwdom_reserved = 0; + + setup_hwdom_pci_devices(d, iommu_add_hwdom_pci_device); } /* diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 4f5de9a542..534faaaa84 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -20,6 +20,7 @@ #include <xen/pci_ids.h> #include <xen/list.h> #include <xen/prefetch.h> +#include <xen/iocap.h> #include <xen/iommu.h> #include <xen/irq.h> #include <xen/param.h> @@ -1040,6 +1041,12 @@ enum pdev_type pdev_type(u16 seg, u8 bus, u8 devfn) return pos ? DEV_TYPE_PCIe_ENDPOINT : DEV_TYPE_PCI; } +static bool pdev_is_endpoint(struct pci_dev *pdev) +{ + enum pdev_type type = pdev_type(pdev->seg, pdev->bus, pdev->devfn); + return type == DEV_TYPE_PCIe_ENDPOINT || type == DEV_TYPE_PCI; +} + /* * find the upstream PCIe-to-PCI/PCIX bridge or PCI legacy bridge * return 0: the device is integrated PCI device or PCIe @@ -1255,7 +1262,7 @@ static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt, struct pci_dev *pdev) { u8 devfn = pdev->devfn; - int err; + int err, i, rc; do { err = ctxt->handler(devfn, pdev); @@ -1276,6 +1283,34 @@ static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt, if ( err ) printk(XENLOG_ERR "setup of vPCI for d%d failed: %d\n", ctxt->d->domain_id, err); + + if ( !hwdom_uses_vpci() ) + return; + + for ( i = 0; i < PCI_HEADER_NORMAL_NR_BARS; i += rc ) + { + uint64_t addr, size; + uint8_t reg = PCI_BASE_ADDRESS_0 + i * 4; + + if ( (pci_conf_read32(pdev->sbdf, reg) & PCI_BASE_ADDRESS_SPACE) + == PCI_BASE_ADDRESS_SPACE_IO ) + { + rc = 1; + continue; + } + + rc = pci_size_mem_bar(pdev->sbdf, reg, &addr, &size, + (i == PCI_HEADER_NORMAL_NR_BARS - 1) + ? PCI_BAR_LAST : 0); + + if ( !size ) + continue; + + err = iomem_permit_access(hardware_domain, paddr_to_pfn(addr), + paddr_to_pfn(PAGE_ALIGN(addr + size - 1))); + if ( err ) + break; + } } static int __hwdom_init cf_check _setup_hwdom_pci_devices( @@ -1294,6 +1329,9 @@ static int __hwdom_init cf_check _setup_hwdom_pci_devices( if ( !pdev ) continue; + if ( hwdom_uses_vpci() && !pdev_is_endpoint(pdev) ) + continue; + if ( !pdev->domain ) { pdev->domain = ctxt->d; -- 2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |