Re: [PATCH v2 13/22] iommufd: Add mmap interface

Jason Gunthorpe
2025-05-07T22:11:11Z

On Wed, May 07, 2025 at 02:09:31PM -0700, Nicolin Chen wrote:
> On Wed, May 07, 2025 at 09:39:01AM -0300, Jason Gunthorpe wrote:
> > On Tue, May 06, 2025 at 12:30:54PM -0700, Nicolin Chen wrote:
> >
> > > So, if I understand it correctly, what we want to achieve is to
> > > have maple tree to manage all PFN ranges. And each range holds
> > > the same entry, a structure that we can use to verify the sanity
> > > of an mmap? Let's say for PFNs A->B, the tree should store the
> > > structure between index A and index B (inclusive)?
> >
> > And tell you what has been mmap'd.
> >
> > > If this is correct, mtree_alloc_range() that is given a range of
> > > [0, ULONG_MAX] would allocate the PFN range from the lowest index
> > > (i.e. 0) instead of PFN A?
> >
> > mtree_alloc_range() returns a new range of PFNs that does not overlap
> > with any existing range. It should always be called on O->U32_MAX (for
> > 32bit uapi compat) and it should always pick the range to use.
>
> Ah, so it's like an address translation table. mtree_alloc_range()
> just gives us a virtual address range (i.e the cookie) for mmap()
> to translate back to the real PFN range.

Yes. It is just a way to adopt the mmap interface - mmap is about
ranges in a logical file, so we want to create logical ranges to refer
to the objects to be mapped.

> I have another question: while I don't think my code is handling
> this well either, how should we validate the input address is an
> allowed one?

The pgoff to mmap? If it isn't in the maple tree it is not allowed, if
it isn't at the start of range it is not allowed, if the size is not
exactly the same as the range it is not allowed.

> Because mmap() is per ictx, i.e. it's a global translation table.

It's per-FD. The pgoff number space is per-fd calling mmap.

> So, the following might happen: let's say we have two vIOMMUs in
> the same ictx. Either vIOMMU has reported a cookie to index the
> mtree for the real PFN range: call them PFN_RANGE0 (for vIOMMU0)
> and PFN_RANGE1 (for vIOMMU1). What if a buggy VMM inverted these
> cookies between the two vIOMMUs, so it would end up with vIOMMU0
> accessing PFN_RANGE1?

Oh well. That is too buggy for the kernel to do anything about. The
mmap cookie comes out of the VIOMMU_ALLOC call and goes back into the
mmap() call, if you mess it up or mix up the pointers then too bad.

But if two VMMs are doing this then they each have their own iommufd
and their own private numberspace and VMM A's VIOMMU cannot be mapped
through VMM B's iommufd FD.

Jason