On Wed, Mar 31, 2021 at 07:41:40AM +0000, Liu, Yi L wrote: > > From: Jason Gunthorpe <jgg@xxxxxxxxxx> > > Sent: Tuesday, March 30, 2021 9:28 PM > > > > On Tue, Mar 30, 2021 at 04:14:58AM +0000, Tian, Kevin wrote: > > > > > One correction. The mdev should still construct the list of allowed PASID's > > as > > > you said (by listening to IOASID_BIND/UNBIND event), in addition to the > > ioasid > > > set maintained per VM (updated when a PASID is allocated/freed). The > > per-VM > > > set is required for inter-VM isolation (verified when a pgtable is bound to > > the > > > mdev/PASID), while the mdev's own list is necessary for intra-VM isolation > > when > > > multiple mdevs are assigned to the same VM (verified before loading a > > PASID > > > to the mdev). This series just handles the general part i.e. per-VM ioasid > > set and > > > leaves the mdev's own list to be managed by specific mdev driver which > > listens > > > to various IOASID events). > > > > This is better, but I don't understand why we need such a convoluted > > design. > > > > Get rid of the ioasid set. > > > > Each driver has its own list of allowed ioasids. > > First, I agree with you it's necessary to have a per-device allowed ioasid > list. But besides it, I think we still need to ensure the ioasid used by a > VM is really allocated to this VM. A VM should not use an ioasid allocated > to another VM. right? Actually, this is the major intention for introducing > ioasid_set. The /dev/ioasid FD replaces this security check. By becoming FD centric you don't need additional kernel security objects. Any process with access to the /dev/ioasid FD is allowed to control those PASID. The seperation between VMs falls naturally from the seperation of FDs without creating additional, complicated, security infrastrucure in the kernel. This is why all APIs must be FD focused, and you need to have a logical layering of responsibility. Allocate a /dev/ioasid FD Allocate PASIDs inside the FD Assign memory to the PASIDS Open a device FD, eg from VFIO or VDP Instruct the device FD to authorize the device to access PASID A in an ioasid FD * Prior to being authorized the device will have NO access to any PASID * Presenting BOTH the device FD and the ioasid FD to the kernel is the security check. Any process with both FDs is allowed to make the connection. This is normal Unix FD centric thinking. > > Register a ioasid in the driver's list by passing the fd and ioasid # > > The fd here is a device fd. Am I right? It would be the vfio_device FD, for instance, and a VFIO IOCTL. > If yes, your idea is ioasid is allocated via /dev/ioasid and > associated with device fd via either VFIO or vDPA ioctl. right? > sorry I may be asking silly questions but really need to ensure we > are talking in the same page. Yes, this is right > > No listening to events. A simple understandable security model. > > For this suggestion, I have a little bit concern if we may have A-B/B-A > lock sequence issue since it requires the /dev/ioasid (if it supports) > to call back into VFIO/VDPA to check if the ioasid has been registered to > device FD and record it in the per-device list. right? Let's have more > discussion based on the skeleton sent by Kevin. Callbacks would be backwards. User calls vfio with vfio_device fd and dev/ioasid fd VFIO extracts some kernel representation of the ioasid from the ioasid fd using an API VFIO does some kernel call to IOMMU/IOASID layer that says 'tell the IOMMU that this PCI device is allowed to use this PASID' VFIO mdev drivers then record that the PASID is allowed in its own device specific struct for later checking during other system calls. No lock inversions. No callbacks. Why do we need callbacks?? Simplify. Jason