[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] xen, vtd: Fix device check for devices behind PCIe-to-PCI bridges



Ah yes, so it is.  Sorry.
 -George

On Tue, Sep 13, 2011 at 11:53 AM, Jan Beulich <JBeulich@xxxxxxxx> wrote:
>>>> On 13.09.11 at 11:12, George Dunlap <George.Dunlap@xxxxxxxxxxxxx> wrote:
>> So what was the verdict on this one?  Is someone going to commit to
>> doing a "fake pdev" thing?  If that's not going to happen before the
>> 4.2 release, I suggest we take this patch in the mean time.
>
> Isn't this -unstable c/s 23813:5535d7ce2673?
>
> Jan
>
>> On Thu, Sep 1, 2011 at 3:20 PM, George Dunlap
>> <george.dunlap@xxxxxxxxxxxxx> wrote:
>>> On some systems, requests devices behind a PCIe-to-PCI bridge all
>>> appear to the IOMMU as though they come from from slot 0, function
>>> 0 on that device; so the mapping code much punch a hole for X:0.0
>>> in the IOMMU for such devices.  When punching the hole, if that device
>>> has already been mapped once, we simply need to check ownership to
>>> make sure it's legal.  To do so, domain_context_mapping_one() will look
>>> up the device for the mapping with pci_get_pdev() and look for the owner.
>>>
>>> However, if there is no device in X:0.0, this look up will fail.
>>>
>>> Rather than returning -ENODEV in this situation (causing a failure in
>>> mapping the device), try to get the domain ownership from the iommu context
>>> mapping itself.
>>>
>>> Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
>>>
>>> diff -r 4a4882df5649 -r ede81b0552be xen/drivers/passthrough/vtd/iommu.c
>>> --- a/xen/drivers/passthrough/vtd/iommu.c       Wed Aug 31 15:23:49 2011 
>>> +0100
>>> +++ b/xen/drivers/passthrough/vtd/iommu.c       Thu Sep 01 15:18:18 2011
>> +0100
>>> @@ -113,6 +113,27 @@ static int context_set_domain_id(struct
>>>     return 0;
>>>  }
>>>
>>> +static int context_get_domain_id(struct context_entry *context,
>>> +                                 struct iommu *iommu)
>>> +{
>>> +    unsigned long dom_index, nr_dom;
>>> +    int domid = -1;
>>> +
>>> +    if (iommu && context)
>>> +    {
>>> +        nr_dom = cap_ndoms(iommu->cap);
>>> +
>>> +        dom_index = context_domain_id(*context);
>>> +
>>> +        if ( dom_index < nr_dom && iommu->domid_map)
>>> +            domid = iommu->domid_map[dom_index];
>>> +        else
>>> +            dprintk(XENLOG_DEBUG VTDPREFIX, "%s: dom_index %lu exceeds
>> nr_dom %lu or iommu has no domid_map\n",
>>> +                    __func__, dom_index, nr_dom);
>>> +    }
>>> +    return domid;
>>> +}
>>> +
>>>  static struct intel_iommu *__init alloc_intel_iommu(void)
>>>  {
>>>     struct intel_iommu *intel;
>>> @@ -1237,7 +1258,6 @@ int domain_context_mapping_one(
>>>     struct hvm_iommu *hd = domain_hvm_iommu(domain);
>>>     struct context_entry *context, *context_entries;
>>>     u64 maddr, pgd_maddr;
>>> -    struct pci_dev *pdev = NULL;
>>>     int agaw;
>>>
>>>     ASSERT(spin_is_locked(&pcidevs_lock));
>>> @@ -1249,12 +1269,45 @@ int domain_context_mapping_one(
>>>     if ( context_present(*context) )
>>>     {
>>>         int res = 0;
>>> +        struct pci_dev *pdev = NULL;
>>>
>>> +        /* First try to get domain ownership from device structure.  If
>> that's
>>> +         * not available, try to read it from the context itself. */
>>>         pdev = pci_get_pdev(bus, devfn);
>>> -        if (!pdev)
>>> -            res = -ENODEV;
>>> -        else if (pdev->domain != domain)
>>> -            res = -EINVAL;
>>> +        if ( pdev )
>>> +        {
>>> +            if ( pdev->domain != domain )
>>> +            {
>>> +                dprintk(XENLOG_INFO VTDPREFIX, "d%d: bdf = %x:%x.%x owned
>> by d%d!",
>>> +                        domain->domain_id,
>>> +                        bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
>>> +                        (pdev->domain)
>>> +                        ? pdev->domain->domain_id : -1);
>>> +                res = -EINVAL;
>>> +            }
>>> +        }
>>> +        else
>>> +        {
>>> +            int cdomain;
>>> +            cdomain = context_get_domain_id(context, iommu);
>>> +
>>> +            if ( cdomain < 0 )
>>> +            {
>>> +                dprintk(VTDPREFIX, "d%d: bdf = %x:%x.%x mapped, but can't
>> find owner!\n",
>>> +                        domain->domain_id,
>>> +                        bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
>>> +                res = -EINVAL;
>>> +            }
>>> +            else if ( cdomain != domain->domain_id )
>>> +            {
>>> +                dprintk(XENLOG_INFO VTDPREFIX, "d%d: bdf = %x:%x.%x already
>> mapped to d%d!",
>>> +                        domain->domain_id,
>>> +                        bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
>>> +                        cdomain);
>>> +                res = -EINVAL;
>>> +            }
>>> +        }
>>> +
>>>         unmap_vtd_domain_page(context_entries);
>>>         spin_unlock(&iommu->lock);
>>>         return res;
>>>
>>> _______________________________________________
>>> Xen-devel mailing list
>>> Xen-devel@xxxxxxxxxxxxxxxxxxx
>>> http://lists.xensource.com/xen-devel
>>>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-devel
>

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.