[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] xen/passthrough: extend hypercall to support rdm reservation policy
commit ab13e3dc788bf06701dd0104feb214b5870e2694 Author: Tiejun Chen <tiejun.chen@xxxxxxxxx> AuthorDate: Wed Jul 22 01:40:11 2015 +0000 Commit: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CommitDate: Thu Jul 23 13:45:25 2015 +0100 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 "strict" or "relaxed" when reserving RDM regions in pfn space. Note in some special cases, e.g. add a device to hwdomain, and remove a device from user domain, 'relaxed' is fine enough since this is always safe to hwdomain. CC: Tim Deegan <tim@xxxxxxx> CC: Keir Fraser <keir@xxxxxxx> CC: Jan Beulich <jbeulich@xxxxxxxx> CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> CC: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@xxxxxxx> CC: Ian Campbell <ian.campbell@xxxxxxxxxx> CC: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx> CC: Yang Zhang <yang.z.zhang@xxxxxxxxx> CC: Kevin Tian <kevin.tian@xxxxxxxxx> Signed-off-by: Tiejun Chen <tiejun.chen@xxxxxxxxx> Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx> Acked-by: Jan Beulich <jbeulich@xxxxxxxx> -- v13a: Fix build on ARM by passing 0 for flags to arm_smmu_assign_dev. --- xen/arch/x86/mm/p2m.c | 7 +++- xen/drivers/passthrough/amd/pci_amd_iommu.c | 3 +- xen/drivers/passthrough/arm/smmu.c | 5 ++- xen/drivers/passthrough/device_tree.c | 3 +- xen/drivers/passthrough/pci.c | 15 ++++++++--- xen/drivers/passthrough/vtd/iommu.c | 37 +++++++++++++++++++++------ xen/include/asm-x86/p2m.h | 2 +- xen/include/public/domctl.h | 3 ++ xen/include/xen/iommu.h | 2 +- 9 files changed, 57 insertions(+), 20 deletions(-) diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 1e763dc..89616b7 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -901,7 +901,7 @@ int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, } int set_identity_p2m_entry(struct domain *d, unsigned long gfn, - p2m_access_t p2ma) + p2m_access_t p2ma, unsigned int flag) { p2m_type_t p2mt; p2m_access_t a; @@ -923,7 +923,10 @@ int set_identity_p2m_entry(struct domain *d, unsigned long gfn, ret = 0; else { - ret = -EBUSY; + if ( flag & XEN_DOMCTL_DEV_RDM_RELAXED ) + ret = 0; + else + ret = -EBUSY; printk(XENLOG_G_WARNING "Cannot setup identity map d%d:%lx," " gfn already mapped to %lx.\n", 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/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c index 6cc4394..be03dff 100644 --- a/xen/drivers/passthrough/arm/smmu.c +++ b/xen/drivers/passthrough/arm/smmu.c @@ -2605,7 +2605,7 @@ static void arm_smmu_destroy_iommu_domain(struct iommu_domain *domain) } static int arm_smmu_assign_dev(struct domain *d, u8 devfn, - struct device *dev) + struct device *dev, u32 flag) { struct iommu_domain *domain; struct arm_smmu_xen_domain *xen_domain; @@ -2709,7 +2709,8 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t, return ret; if (t) { - ret = arm_smmu_assign_dev(t, devfn, dev); + /* No flags are defined for ARM. */ + ret = arm_smmu_assign_dev(t, devfn, dev, 0); if (ret) return ret; } diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c index 5d3842a..7ff79f8 100644 --- a/xen/drivers/passthrough/device_tree.c +++ b/xen/drivers/passthrough/device_tree.c @@ -52,7 +52,8 @@ int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev) goto fail; } - rc = hd->platform_ops->assign_device(d, 0, dt_to_dev(dev)); + /* The flag field doesn't matter to DT device. */ + rc = hd->platform_ops->assign_device(d, 0, dt_to_dev(dev), 0); if ( rc ) goto fail; diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 8632265..3057b11 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -1334,7 +1334,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; @@ -1370,7 +1370,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 ) @@ -1378,7 +1378,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), @@ -1495,6 +1495,7 @@ int iommu_do_pci_domctl( { u16 seg; u8 bus, devfn; + u32 flag; int ret = 0; uint32_t machine_sbdf; @@ -1576,9 +1577,15 @@ int iommu_do_pci_domctl( seg = machine_sbdf >> 16; bus = PCI_BUS(machine_sbdf); devfn = PCI_DEVFN2(machine_sbdf); + flag = domctl->u.assign_device.flag; + if ( flag & ~XEN_DOMCTL_DEV_RDM_RELAXED ) + { + ret = -EINVAL; + break; + } 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 5aa482f..a2f3a66 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1807,7 +1807,8 @@ static void iommu_set_pgd(struct domain *d) } 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; @@ -1855,7 +1856,7 @@ static int rmrr_identity_mapping(struct domain *d, bool_t map, while ( base_pfn < end_pfn ) { - int err = set_identity_p2m_entry(d, base_pfn, p2m_access_rw); + int err = set_identity_p2m_entry(d, base_pfn, p2m_access_rw, flag); if ( err ) return err; @@ -1898,7 +1899,13 @@ 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); + /* + * iommu_add_device() is only called for the hardware + * domain (see xen/drivers/passthrough/pci.c:pci_add_device()). + * Since RMRRs are always reserved in the e820 map for the hardware + * domain, there shouldn't be a conflict. + */ + ret = rmrr_identity_mapping(pdev->domain, 1, rmrr, 0); if ( ret ) dprintk(XENLOG_ERR VTDPREFIX, "d%d: RMRR mapping failed\n", pdev->domain->domain_id); @@ -1939,7 +1946,11 @@ static int intel_iommu_remove_device(u8 devfn, struct pci_dev *pdev) PCI_DEVFN2(bdf) != devfn ) continue; - rmrr_identity_mapping(pdev->domain, 0, rmrr); + /* + * Any flag is nothing to clear these mappings but here + * its always safe and strict to set 0. + */ + rmrr_identity_mapping(pdev->domain, 0, rmrr, 0); } return domain_context_unmap(pdev->domain, devfn, pdev); @@ -2097,7 +2108,13 @@ 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); + /* + * Here means we're add a device to the hardware domain. + * Since RMRRs are always reserved in the e820 map for the hardware + * domain, there shouldn't be a conflict. So its always safe and + * strict to set 0. + */ + ret = rmrr_identity_mapping(d, 1, rmrr, 0); if ( ret ) dprintk(XENLOG_ERR VTDPREFIX, "IOMMU: mapping reserved region failed\n"); @@ -2240,7 +2257,11 @@ static int reassign_device_ownership( PCI_BUS(bdf) == pdev->bus && PCI_DEVFN2(bdf) == devfn ) { - ret = rmrr_identity_mapping(source, 0, rmrr); + /* + * Any RMRR flag is always ignored when remove a device, + * but its always safe and strict to set 0. + */ + ret = rmrr_identity_mapping(source, 0, rmrr, 0); if ( ret != -ENOENT ) return ret; } @@ -2264,7 +2285,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; @@ -2293,7 +2314,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/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 190a286..68da0a9 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -545,7 +545,7 @@ int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn); /* Set identity addresses in the p2m table (for pass-through) */ int set_identity_p2m_entry(struct domain *d, unsigned long gfn, - p2m_access_t p2ma); + p2m_access_t p2ma, unsigned int flag); #define clear_identity_p2m_entry(d, gfn, page_order) \ guest_physmap_remove_page(d, gfn, gfn, page_order) diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 631935a..675f021 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -471,6 +471,9 @@ struct xen_domctl_assign_device { XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */ } dt; } u; + /* IN */ +#define XEN_DOMCTL_DEV_RDM_RELAXED 1 + uint32_t 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 52ed3b7..1124601 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -139,7 +139,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 -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |