[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC][PATCH 07/13] xen/passthrough: extend hypercall to support rdm reservation policy
This patch extends the existing hypercall to support rdm reservation policy. We return error or just throw out a warning message depending on whether the policy is 'force' or 'try'. Signed-off-by: Tiejun Chen <tiejun.chen@xxxxxxxxx> --- xen/drivers/passthrough/amd/pci_amd_iommu.c | 3 ++- xen/drivers/passthrough/pci.c | 10 +++++---- xen/drivers/passthrough/vtd/iommu.c | 32 +++++++++++++++++++++-------- xen/include/public/domctl.h | 4 ++++ xen/include/xen/iommu.h | 2 +- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c index e83bb35..920b35a 100644 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c @@ -394,7 +394,8 @@ static int reassign_device(struct domain *source, struct domain *target, } static int amd_iommu_assign_device(struct domain *d, u8 devfn, - struct pci_dev *pdev) + struct pci_dev *pdev, + u32 flag) { struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(pdev->seg); int bdf = PCI_BDF2(pdev->bus, devfn); diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 4b83583..1b040d9 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -1333,7 +1333,7 @@ static int device_assigned(u16 seg, u8 bus, u8 devfn) return pdev ? 0 : -EBUSY; } -static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn) +static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag) { struct hvm_iommu *hd = domain_hvm_iommu(d); struct pci_dev *pdev; @@ -1383,7 +1383,7 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn) pdev->fault.count = 0; - if ( (rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev))) ) + if ( (rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev), flag)) ) goto done; for ( ; pdev->phantom_stride; rc = 0 ) @@ -1391,7 +1391,7 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn) devfn += pdev->phantom_stride; if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) ) break; - rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev)); + rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev), flag); if ( rc ) printk(XENLOG_G_WARNING "d%d: assign %04x:%02x:%02x.%u failed (%d)\n", d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), @@ -1508,6 +1508,7 @@ int iommu_do_pci_domctl( { u16 seg; u8 bus, devfn; + u32 flag; int ret = 0; switch ( domctl->cmd ) @@ -1576,9 +1577,10 @@ int iommu_do_pci_domctl( seg = domctl->u.assign_device.machine_sbdf >> 16; bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff; devfn = domctl->u.assign_device.machine_sbdf & 0xff; + flag = domctl->u.assign_device.sbdf_flag; ret = device_assigned(seg, bus, devfn) ?: - assign_device(d, seg, bus, devfn); + assign_device(d, seg, bus, devfn, flag); if ( ret == -ERESTART ) ret = hypercall_create_continuation(__HYPERVISOR_domctl, "h", u_domctl); diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index f8fc6c3..2681166 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1793,8 +1793,14 @@ static void iommu_set_pgd(struct domain *d) hd->arch.pgd_maddr = pagetable_get_paddr(pagetable_from_mfn(pgd_mfn)); } +/* + * In some cases, e.g. add a device to hwdomain, and remove a device from + * user domain, 'try' is fine enough since this is always safe to hwdomain. + */ +#define XEN_DOMCTL_PCIDEV_RDM_DEFAULT XEN_DOMCTL_PCIDEV_RDM_TRY static int rmrr_identity_mapping(struct domain *d, bool_t map, - const struct acpi_rmrr_unit *rmrr) + const struct acpi_rmrr_unit *rmrr, + u32 flag) { unsigned long base_pfn = rmrr->base_address >> PAGE_SHIFT_4K; unsigned long end_pfn = PAGE_ALIGN_4K(rmrr->end_address) >> PAGE_SHIFT_4K; @@ -1851,7 +1857,14 @@ static int rmrr_identity_mapping(struct domain *d, bool_t map, if ( !is_hardware_domain(d) ) { if ( (err = set_identity_p2m_entry(d, base_pfn, p2m_access_rw)) ) - return err; + { + if ( flag == XEN_DOMCTL_PCIDEV_RDM_TRY ) + { + printk(XENLOG_G_WARNING "Some devices may work failed .\n"); + } + else + return err; + } } base_pfn++; } @@ -1892,7 +1905,8 @@ static int intel_iommu_add_device(u8 devfn, struct pci_dev *pdev) PCI_BUS(bdf) == pdev->bus && PCI_DEVFN2(bdf) == devfn ) { - ret = rmrr_identity_mapping(pdev->domain, 1, rmrr); + ret = rmrr_identity_mapping(pdev->domain, 1, rmrr, + XEN_DOMCTL_PCIDEV_RDM_DEFAULT); if ( ret ) dprintk(XENLOG_ERR VTDPREFIX, "d%d: RMRR mapping failed\n", pdev->domain->domain_id); @@ -1933,7 +1947,8 @@ static int intel_iommu_remove_device(u8 devfn, struct pci_dev *pdev) PCI_DEVFN2(bdf) != devfn ) continue; - rmrr_identity_mapping(pdev->domain, 0, rmrr); + rmrr_identity_mapping(pdev->domain, 0, rmrr, + XEN_DOMCTL_PCIDEV_RDM_DEFAULT); } return domain_context_unmap(pdev->domain, devfn, pdev); @@ -2091,7 +2106,7 @@ static void __hwdom_init setup_hwdom_rmrr(struct domain *d) spin_lock(&pcidevs_lock); for_each_rmrr_device ( rmrr, bdf, i ) { - ret = rmrr_identity_mapping(d, 1, rmrr); + ret = rmrr_identity_mapping(d, 1, rmrr, XEN_DOMCTL_PCIDEV_RDM_DEFAULT); if ( ret ) dprintk(XENLOG_ERR VTDPREFIX, "IOMMU: mapping reserved region failed\n"); @@ -2234,7 +2249,8 @@ static int reassign_device_ownership( PCI_BUS(bdf) == pdev->bus && PCI_DEVFN2(bdf) == devfn ) { - ret = rmrr_identity_mapping(source, 0, rmrr); + ret = rmrr_identity_mapping(source, 0, rmrr, + XEN_DOMCTL_PCIDEV_RDM_DEFAULT); if ( ret != -ENOENT ) return ret; } @@ -2258,7 +2274,7 @@ static int reassign_device_ownership( } static int intel_iommu_assign_device( - struct domain *d, u8 devfn, struct pci_dev *pdev) + struct domain *d, u8 devfn, struct pci_dev *pdev, u32 flag) { struct acpi_rmrr_unit *rmrr; int ret = 0, i; @@ -2287,7 +2303,7 @@ static int intel_iommu_assign_device( PCI_BUS(bdf) == bus && PCI_DEVFN2(bdf) == devfn ) { - ret = rmrr_identity_mapping(d, 1, rmrr); + ret = rmrr_identity_mapping(d, 1, rmrr, flag); if ( ret ) { reassign_device_ownership(d, hardware_domain, devfn, pdev); diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index ca0e51e..e5ba7cb 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -493,6 +493,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t); /* XEN_DOMCTL_deassign_device */ struct xen_domctl_assign_device { uint32_t machine_sbdf; /* machine PCI ID of assigned device */ + /* IN */ +#define XEN_DOMCTL_PCIDEV_RDM_TRY 0 +#define XEN_DOMCTL_PCIDEV_RDM_FORCE 1 + uint32_t sbdf_flag; /* flag of assigned device */ }; typedef struct xen_domctl_assign_device xen_domctl_assign_device_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t); diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index 8565b82..0d10b3d 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -129,7 +129,7 @@ struct iommu_ops { int (*add_device)(u8 devfn, device_t *dev); int (*enable_device)(device_t *dev); int (*remove_device)(u8 devfn, device_t *dev); - int (*assign_device)(struct domain *, u8 devfn, device_t *dev); + int (*assign_device)(struct domain *, u8 devfn, device_t *dev, u32 flag); int (*reassign_device)(struct domain *s, struct domain *t, u8 devfn, device_t *dev); #ifdef HAS_PCI -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |