On Wed, Jan 18, 2017 at 03:49:44PM +0800, Peter Xu wrote: [...]
> I was trying to invalidate the entire address space by sending a big > IOTLB notification to vfio-pci, which looks like: > > IOMMUTLBEntry entry = { > .target_as = &address_space_memory, > .iova = 0, > .translated_addr = 0, > .addr_mask = (1 << 63) - 1, > .perm = IOMMU_NONE, /* UNMAP */ > }; > > Then I feed this entry to vfio-pci IOMMU notifier. > > However, this was blocked in vfio_iommu_map_notify(), with error: > > qemu-system-x86_64: iommu has granularity incompatible with target AS > > Since we have: > > /* > * The IOMMU TLB entry we have just covers translation through > * this IOMMU to its immediate target. We need to translate > * it the rest of the way through to memory. > */ > rcu_read_lock(); > mr = address_space_translate(&address_space_memory, > iotlb->translated_addr, > &xlat, &len, iotlb->perm & IOMMU_WO); > if (!memory_region_is_ram(mr)) { > error_report("iommu map to non memory area %"HWADDR_PRIx"", > xlat); > goto out; > } > /* > * Translation truncates length to the IOMMU page size, > * check that it did not truncate too much. > */ > if (len & iotlb->addr_mask) { > error_report("iommu has granularity incompatible with target AS"); > goto out; > } > > In my case len == 0xa0000 (that's the translation result), and > iotlb->addr_mask == (1<<63)-1. So looks like the translation above > splitted the big region and a simple big UNMAP doesn't work for me. > > Do you have any suggestion on how I can solve this? In what case will > we need the above address_space_translate()? Hmm... it should be checking that the translated address range is RAM. However if with this, IOMMU notifiers won't be able to leverage the vfio driver feature to unmap a very big region. IMHO the check should only be meaningful for map operations. I'll try to post a RFC patch for vfio-pci to allow unmap of very big regions, to see whether that'll be a workable approach. Thanks, -- peterx