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

Re: [Xen-devel] [PATCH v4 01/10] vt-d: fix the IOMMU flush issue



>>> On 12.05.16 at 09:50, <quan.xu@xxxxxxxxx> wrote:
> On May 10, 2016 12:10 AM, Jan Beulich <JBeulich@xxxxxxxx> wrote:
>> >>> On 06.05.16 at 10:54, <quan.xu@xxxxxxxxx> wrote:
>> > -static void intel_iommu_iotlb_flush(struct domain *d, unsigned long
>> > gfn, unsigned int page_count)
>> > +static void iommu_flush_iotlb_page(struct domain *d, unsigned long gfn,
>> > +                                   unsigned int page_count)
>> 
>> The new name suggests just one page. Please use e.g.
>> iommu_flush_iotlb_pages() instead.
>> 
> 
> Make sense. 
> 
>> >  {
>> > -    __intel_iommu_iotlb_flush(d, gfn, 1, page_count);
>> > +    iommu_flush_iotlb(d, gfn, 1, page_count);
>> >  }
>> 
>> But of course the question is whether having this wrapper is useful in the 
>> first
>> place,
> 
> 
> This wrapper assumes the 'dma_old_pte_present' is '1', but in another caller 
> intel_iommu_map_page(), i.e. 
> 
> 
>      intel_iommu_map_page()
>     {
>        ...
>              if ( !this_cpu(iommu_dont_flush_iotlb) )
>                   iommu_flush_iotlb(d, gfn, dma_pte_present(old), 1);
>        ...
>     }
> 
> 
> the 'dma_old_pte_present' is not sure. 

I'm sorry, but you're looking at this backwards: I suggested to
remove the wrapper, not to move any check into iommu_flush_iotlb().
Removing the wrapper simply means to move the passing of the
hard coded 1 into the current callers of that wrapper.

>> > @@ -1391,13 +1399,19 @@ int domain_context_mapping_one(
>> >      spin_unlock(&iommu->lock);
>> >
>> >      /* Context entry was previously non-present (with domid 0). */
>> > -    if ( iommu_flush_context_device(iommu, 0, (((u16)bus) << 8) | devfn,
>> > -                                    DMA_CCMD_MASK_NOBIT, 1) )
>> > -        iommu_flush_write_buffer(iommu);
>> > -    else
>> > +    rc = iommu_flush_context_device(iommu, 0, (((u16)bus) << 8) | devfn,
>> > +                                    DMA_CCMD_MASK_NOBIT, 1);
>> > +
>> > +    if ( !rc )
>> >      {
>> >          int flush_dev_iotlb = find_ats_dev_drhd(iommu) ? 1 : 0;
>> > -        iommu_flush_iotlb_dsi(iommu, 0, 1, flush_dev_iotlb);
>> > +        rc = iommu_flush_iotlb_dsi(iommu, 0, 1, flush_dev_iotlb);
>> 
>> Please take the opportunity and add the missing blank line (between
>> declaration(s) and statement(s) in cases like this.
>> 
>> > +    }
>> > +
>> > +    if ( rc > 0 )
>> 
>> Can iommu_flush_context_device() return a positive value? If so, the logic is
>> now likely wrong. If not (which is what I assume) I'd like to suggest adding 
>> a
>> respective ASSERT() (even if only to document the fact). Or alternatively 
>> this
>> if() could move into the immediately preceding one.
> 
> Check it again. iommu_flush_context_device() can return a positive value.
> [...]
> Could you tell me why the logic is now likely wrong? I will fix it first.

With

    rc = iommu_flush_context_device(iommu, 0, (((u16)bus) << 8) | devfn,
                                    DMA_CCMD_MASK_NOBIT, 1);

    if ( !rc )
    {
        int flush_dev_iotlb = find_ats_dev_drhd(iommu) ? 1 : 0;
        rc = iommu_flush_iotlb_dsi(iommu, 0, 1, flush_dev_iotlb);
    }

    if ( rc > 0 )
    {
        iommu_flush_write_buffer(iommu);
        rc = 0;
    }

it seems pretty clear that you won't call iommu_flush_iotlb_dsi() if
iommu_flush_context_device() returned 1, which doesn't look like
what is wanted at the first glance. But I may be wrong, hence the
"likely" in my earlier reply.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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