Skip to content
  • Kirti Wankhede's avatar
    vfio: Mediated device Core driver · 7b96953b
    Kirti Wankhede authored
    
    
    Design for Mediated Device Driver:
    Main purpose of this driver is to provide a common interface for mediated
    device management that can be used by different drivers of different
    devices.
    
    This module provides a generic interface to create the device, add it to
    mediated bus, add device to IOMMU group and then add it to vfio group.
    
    Below is the high Level block diagram, with Nvidia, Intel and IBM devices
    as example, since these are the devices which are going to actively use
    this module as of now.
    
     +---------------+
     |               |
     | +-----------+ |  mdev_register_driver() +--------------+
     | |           | +<------------------------+ __init()     |
     | |  mdev     | |                         |              |
     | |  bus      | +------------------------>+              |<-> VFIO user
     | |  driver   | |     probe()/remove()    | vfio_mdev.ko |    APIs
     | |           | |                         |              |
     | +-----------+ |                         +--------------+
     |               |
     |  MDEV CORE    |
     |   MODULE      |
     |   mdev.ko     |
     | +-----------+ |  mdev_register_device() +--------------+
     | |           | +<------------------------+              |
     | |           | |                         |  nvidia.ko   |<-> physical
     | |           | +------------------------>+              |    device
     | |           | |        callback         +--------------+
     | | Physical  | |
     | |  device   | |  mdev_register_device() +--------------+
     | | interface | |<------------------------+              |
     | |           | |                         |  i915.ko     |<-> physical
     | |           | +------------------------>+              |    device
     | |           | |        callback         +--------------+
     | |           | |
     | |           | |  mdev_register_device() +--------------+
     | |           | +<------------------------+              |
     | |           | |                         | ccw_device.ko|<-> physical
     | |           | +------------------------>+              |    device
     | |           | |        callback         +--------------+
     | +-----------+ |
     +---------------+
    
    Core driver provides two types of registration interfaces:
    1. Registration interface for mediated bus driver:
    
    /**
      * struct mdev_driver - Mediated device's driver
      * @name: driver name
      * @probe: called when new device created
      * @remove:called when device removed
      * @driver:device driver structure
      *
      **/
    struct mdev_driver {
             const char *name;
             int  (*probe)  (struct device *dev);
             void (*remove) (struct device *dev);
             struct device_driver    driver;
    };
    
    Mediated bus driver for mdev device should use this interface to register
    and unregister with core driver respectively:
    
    int  mdev_register_driver(struct mdev_driver *drv, struct module *owner);
    void mdev_unregister_driver(struct mdev_driver *drv);
    
    Mediated bus driver is responsible to add/delete mediated devices to/from
    VFIO group when devices are bound and unbound to the driver.
    
    2. Physical device driver interface
    This interface provides vendor driver the set APIs to manage physical
    device related work in its driver. APIs are :
    
    * dev_attr_groups: attributes of the parent device.
    * mdev_attr_groups: attributes of the mediated device.
    * supported_type_groups: attributes to define supported type. This is
    			 mandatory field.
    * create: to allocate basic resources in vendor driver for a mediated
             device. This is mandatory to be provided by vendor driver.
    * remove: to free resources in vendor driver when mediated device is
             destroyed. This is mandatory to be provided by vendor driver.
    * open: open callback of mediated device
    * release: release callback of mediated device
    * read : read emulation callback.
    * write: write emulation callback.
    * ioctl: ioctl callback.
    * mmap: mmap emulation callback.
    
    Drivers should use these interfaces to register and unregister device to
    mdev core driver respectively:
    
    extern int  mdev_register_device(struct device *dev,
                                     const struct parent_ops *ops);
    extern void mdev_unregister_device(struct device *dev);
    
    There are no locks to serialize above callbacks in mdev driver and
    vfio_mdev driver. If required, vendor driver can have locks to serialize
    above APIs in their driver.
    
    Signed-off-by: default avatarKirti Wankhede <kwankhede@nvidia.com>
    Signed-off-by: default avatarNeo Jia <cjia@nvidia.com>
    Reviewed-by: default avatarJike Song <jike.song@intel.com>
    Reviewed-by: default avatarDong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
    Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
    7b96953b