WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH] xen, vtd: Fix device check for devices behind PC

To: Jan Beulich <JBeulich@xxxxxxxx>
Subject: Re: [Xen-devel] [PATCH] xen, vtd: Fix device check for devices behind PCIe-to-PCI bridges
From: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
Date: Wed, 14 Sep 2011 09:48:57 +0100
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx, Keir Fraser <keir@xxxxxxx>
Delivery-date: Wed, 14 Sep 2011 01:49:38 -0700
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=XpPGWHgpgKvxIQYrnaM4lWIM4f0xVJQ1cs5kMgV5Z84=; b=jJgSCkPhydrgvbZKN49dJXkOc7tQqd3sPq41UWvdxSQnyRSGSOqLq43bBWp2a2mm7z 3nPD6jeIGBRwZ2dnRzpzWQuljfrhlC5Klhcb6Iq11QOcRkgrVmNNC3LPjF7FGAPU9m2O LZ+IT1noAAbpsvkfZSoelSnp5Sa44B3L93PO0=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <4E6F52430200007800055D18@xxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <ede81b0552be5b4d1004.1314886804@elijah> <CAFLBxZbhDZ+W2d4mtD61-sM9tnkMSXaG=HHo=Oz1=j+YoDhWeQ@xxxxxxxxxxxxxx> <4E6F52430200007800055D18@xxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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