[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [v8][PATCH 03/16] xen/passthrough: extend hypercall to support rdm reservation policy
On Thu, Jul 16, 2015 at 7:52 AM, Tiejun Chen <tiejun.chen@xxxxxxxxx> wrote: > 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> With or without the "flags &" change: Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx> > --- > v8: > > * Force to pass "0"(strict) when add or move a device in hardware domain, > and improve some associated code comments. > > v6 ~ v7: > > * Nothing is changed. > > v5: > > * Just leave one bit XEN_DOMCTL_DEV_RDM_RELAXED as our flag, so > "0" means "strict" and "1" means "relaxed". > > * So make DT device ignore the flag field > > * Improve the code comments > > v4: > > * Add code comments to describer why we fix to set a policy flag in some > cases like adding a device to hwdomain, and removing a device from user > domain. > > * Avoid using fixed width types for the parameter of set_identity_p2m_entry() > > * Fix one judging condition > domctl->u.assign_device.flag == XEN_DOMCTL_DEV_NO_RDM > -> domctl->u.assign_device.flag != XEN_DOMCTL_DEV_NO_RDM > > * Add to range check the flag passed to make future extensions possible > (and to avoid ambiguity on what out of range values would mean). > > xen/arch/x86/mm/p2m.c | 7 ++++-- > xen/drivers/passthrough/amd/pci_amd_iommu.c | 3 ++- > xen/drivers/passthrough/arm/smmu.c | 2 +- > 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, 55 insertions(+), 19 deletions(-) > > diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c > index 99a26ca..47785dc 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..9a667e9 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; > 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 e30be43..6e23fc6 100644 > --- a/xen/drivers/passthrough/pci.c > +++ b/xen/drivers/passthrough/pci.c > @@ -1335,7 +1335,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; > @@ -1371,7 +1371,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 ) > @@ -1379,7 +1379,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), > @@ -1496,6 +1496,7 @@ int iommu_do_pci_domctl( > { > u16 seg; > u8 bus, devfn; > + u32 flag; > int ret = 0; > uint32_t machine_sbdf; > > @@ -1577,9 +1578,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 8415958..b5d658e 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); > @@ -2098,7 +2109,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"); > @@ -2241,7 +2258,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; > } > @@ -2265,7 +2286,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; > @@ -2294,7 +2315,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 bc45ea5..bca25c9 100644 > --- a/xen/include/public/domctl.h > +++ b/xen/include/public/domctl.h > @@ -478,6 +478,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 e2f584d..02b2b02 100644 > --- a/xen/include/xen/iommu.h > +++ b/xen/include/xen/iommu.h > @@ -140,7 +140,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 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |