2019-06-04 16:11:33 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2016-11-17 04:46:13 +08:00
|
|
|
/*
|
|
|
|
* Mediated device definition
|
|
|
|
*
|
|
|
|
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
|
|
|
* Author: Neo Jia <cjia@nvidia.com>
|
|
|
|
* Kirti Wankhede <kwankhede@nvidia.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef MDEV_H
|
|
|
|
#define MDEV_H
|
|
|
|
|
2021-04-07 03:40:28 +08:00
|
|
|
struct mdev_type;
|
|
|
|
|
2021-04-07 03:40:26 +08:00
|
|
|
struct mdev_device {
|
|
|
|
struct device dev;
|
|
|
|
guid_t uuid;
|
|
|
|
void *driver_data;
|
|
|
|
struct list_head next;
|
2021-04-07 03:40:28 +08:00
|
|
|
struct mdev_type *type;
|
2021-04-07 03:40:26 +08:00
|
|
|
struct device *iommu_device;
|
|
|
|
bool active;
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline struct mdev_device *to_mdev_device(struct device *dev)
|
|
|
|
{
|
|
|
|
return container_of(dev, struct mdev_device, dev);
|
|
|
|
}
|
2016-11-17 04:46:13 +08:00
|
|
|
|
2019-04-12 12:13:24 +08:00
|
|
|
/*
|
|
|
|
* Called by the parent device driver to set the device which represents
|
|
|
|
* this mdev in iommu protection scope. By default, the iommu device is
|
|
|
|
* NULL, that indicates using vendor defined isolation.
|
|
|
|
*
|
|
|
|
* @dev: the mediated device that iommu will isolate.
|
|
|
|
* @iommu_device: a pci device which represents the iommu for @dev.
|
|
|
|
*/
|
2021-04-07 03:40:26 +08:00
|
|
|
static inline void mdev_set_iommu_device(struct mdev_device *mdev,
|
|
|
|
struct device *iommu_device)
|
|
|
|
{
|
|
|
|
mdev->iommu_device = iommu_device;
|
|
|
|
}
|
2019-04-12 12:13:24 +08:00
|
|
|
|
2021-04-07 03:40:26 +08:00
|
|
|
static inline struct device *mdev_get_iommu_device(struct mdev_device *mdev)
|
|
|
|
{
|
|
|
|
return mdev->iommu_device;
|
|
|
|
}
|
2019-04-12 12:13:24 +08:00
|
|
|
|
2021-04-07 03:40:34 +08:00
|
|
|
unsigned int mdev_get_type_group_id(struct mdev_device *mdev);
|
vfio/mdev: Correct the function signatures for the mdev_type_attributes
The driver core standard is to pass in the properly typed object, the
properly typed attribute and the buffer data. It stems from the root
kobject method:
ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,..)
Each subclass of kobject should provide their own function with the same
signature but more specific types, eg struct device uses:
ssize_t (*show)(struct device *dev, struct device_attribute *attr,..)
In this case the existing signature is:
ssize_t (*show)(struct kobject *kobj, struct device *dev,..)
Where kobj is a 'struct mdev_type *' and dev is 'mdev_type->parent->dev'.
Change the mdev_type related sysfs attribute functions to:
ssize_t (*show)(struct mdev_type *mtype, struct mdev_type_attribute *attr,..)
In order to restore type safety and match the driver core standard
There are no current users of 'attr', but if it is ever needed it would be
hard to add in retroactively, so do it now.
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Message-Id: <18-v2-d36939638fc6+d54-vfio2_jgg@nvidia.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2021-04-07 03:40:41 +08:00
|
|
|
unsigned int mtype_get_type_group_id(struct mdev_type *mtype);
|
|
|
|
struct device *mtype_get_parent_dev(struct mdev_type *mtype);
|
2021-04-07 03:40:34 +08:00
|
|
|
|
2016-11-17 04:46:13 +08:00
|
|
|
/**
|
2016-12-30 23:13:38 +08:00
|
|
|
* struct mdev_parent_ops - Structure to be registered for each parent device to
|
2016-11-17 04:46:13 +08:00
|
|
|
* register the device to mdev module.
|
|
|
|
*
|
|
|
|
* @owner: The module owner.
|
2021-06-17 22:22:15 +08:00
|
|
|
* @device_driver: Which device driver to probe() on newly created devices
|
2016-11-17 04:46:13 +08:00
|
|
|
* @dev_attr_groups: Attributes of the parent device.
|
|
|
|
* @mdev_attr_groups: Attributes of the mediated device.
|
|
|
|
* @supported_type_groups: Attributes to define supported types. It is mandatory
|
|
|
|
* to provide supported types.
|
|
|
|
* @create: Called to allocate basic resources in parent device's
|
|
|
|
* driver for a particular mediated device. It is
|
|
|
|
* mandatory to provide create ops.
|
|
|
|
* @mdev: mdev_device structure on of mediated device
|
|
|
|
* that is being created
|
|
|
|
* Returns integer: success (0) or error (< 0)
|
2021-02-26 09:20:56 +08:00
|
|
|
* @remove: Called to free resources in parent device's driver for
|
2016-11-17 04:46:13 +08:00
|
|
|
* a mediated device. It is mandatory to provide 'remove'
|
|
|
|
* ops.
|
|
|
|
* @mdev: mdev_device device structure which is being
|
|
|
|
* destroyed
|
|
|
|
* Returns integer: success (0) or error (< 0)
|
|
|
|
* @open: Open mediated device.
|
|
|
|
* @mdev: mediated device.
|
|
|
|
* Returns integer: success (0) or error (< 0)
|
|
|
|
* @release: release mediated device
|
|
|
|
* @mdev: mediated device.
|
|
|
|
* @read: Read emulation callback
|
|
|
|
* @mdev: mediated device structure
|
|
|
|
* @buf: read buffer
|
|
|
|
* @count: number of bytes to read
|
|
|
|
* @ppos: address.
|
|
|
|
* Retuns number on bytes read on success or error.
|
|
|
|
* @write: Write emulation callback
|
|
|
|
* @mdev: mediated device structure
|
|
|
|
* @buf: write buffer
|
|
|
|
* @count: number of bytes to be written
|
|
|
|
* @ppos: address.
|
|
|
|
* Retuns number on bytes written on success or error.
|
|
|
|
* @ioctl: IOCTL callback
|
|
|
|
* @mdev: mediated device structure
|
|
|
|
* @cmd: ioctl command
|
|
|
|
* @arg: arguments to ioctl
|
|
|
|
* @mmap: mmap callback
|
|
|
|
* @mdev: mediated device structure
|
|
|
|
* @vma: vma structure
|
2020-12-04 05:35:11 +08:00
|
|
|
* @request: request callback to release device
|
|
|
|
* @mdev: mediated device structure
|
|
|
|
* @count: request sequence number
|
2016-11-17 04:46:13 +08:00
|
|
|
* Parent device that support mediated device should be registered with mdev
|
2016-12-30 23:13:38 +08:00
|
|
|
* module with mdev_parent_ops structure.
|
2016-11-17 04:46:13 +08:00
|
|
|
**/
|
2016-12-30 23:13:38 +08:00
|
|
|
struct mdev_parent_ops {
|
2016-11-17 04:46:13 +08:00
|
|
|
struct module *owner;
|
2021-06-17 22:22:15 +08:00
|
|
|
struct mdev_driver *device_driver;
|
2016-11-17 04:46:13 +08:00
|
|
|
const struct attribute_group **dev_attr_groups;
|
|
|
|
const struct attribute_group **mdev_attr_groups;
|
|
|
|
struct attribute_group **supported_type_groups;
|
|
|
|
|
2021-04-07 03:40:40 +08:00
|
|
|
int (*create)(struct mdev_device *mdev);
|
2016-11-17 04:46:13 +08:00
|
|
|
int (*remove)(struct mdev_device *mdev);
|
|
|
|
int (*open)(struct mdev_device *mdev);
|
|
|
|
void (*release)(struct mdev_device *mdev);
|
|
|
|
ssize_t (*read)(struct mdev_device *mdev, char __user *buf,
|
|
|
|
size_t count, loff_t *ppos);
|
|
|
|
ssize_t (*write)(struct mdev_device *mdev, const char __user *buf,
|
|
|
|
size_t count, loff_t *ppos);
|
2017-01-05 04:08:15 +08:00
|
|
|
long (*ioctl)(struct mdev_device *mdev, unsigned int cmd,
|
2016-11-17 04:46:13 +08:00
|
|
|
unsigned long arg);
|
|
|
|
int (*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma);
|
2020-12-04 05:35:11 +08:00
|
|
|
void (*request)(struct mdev_device *mdev, unsigned int count);
|
2016-11-17 04:46:13 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/* interface for exporting mdev supported type attributes */
|
|
|
|
struct mdev_type_attribute {
|
|
|
|
struct attribute attr;
|
vfio/mdev: Correct the function signatures for the mdev_type_attributes
The driver core standard is to pass in the properly typed object, the
properly typed attribute and the buffer data. It stems from the root
kobject method:
ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,..)
Each subclass of kobject should provide their own function with the same
signature but more specific types, eg struct device uses:
ssize_t (*show)(struct device *dev, struct device_attribute *attr,..)
In this case the existing signature is:
ssize_t (*show)(struct kobject *kobj, struct device *dev,..)
Where kobj is a 'struct mdev_type *' and dev is 'mdev_type->parent->dev'.
Change the mdev_type related sysfs attribute functions to:
ssize_t (*show)(struct mdev_type *mtype, struct mdev_type_attribute *attr,..)
In order to restore type safety and match the driver core standard
There are no current users of 'attr', but if it is ever needed it would be
hard to add in retroactively, so do it now.
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Message-Id: <18-v2-d36939638fc6+d54-vfio2_jgg@nvidia.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2021-04-07 03:40:41 +08:00
|
|
|
ssize_t (*show)(struct mdev_type *mtype,
|
|
|
|
struct mdev_type_attribute *attr, char *buf);
|
|
|
|
ssize_t (*store)(struct mdev_type *mtype,
|
|
|
|
struct mdev_type_attribute *attr, const char *buf,
|
|
|
|
size_t count);
|
2016-11-17 04:46:13 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#define MDEV_TYPE_ATTR(_name, _mode, _show, _store) \
|
|
|
|
struct mdev_type_attribute mdev_type_attr_##_name = \
|
|
|
|
__ATTR(_name, _mode, _show, _store)
|
|
|
|
#define MDEV_TYPE_ATTR_RW(_name) \
|
|
|
|
struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_RW(_name)
|
|
|
|
#define MDEV_TYPE_ATTR_RO(_name) \
|
|
|
|
struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_RO(_name)
|
|
|
|
#define MDEV_TYPE_ATTR_WO(_name) \
|
|
|
|
struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_WO(_name)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct mdev_driver - Mediated device driver
|
|
|
|
* @probe: called when new device created
|
|
|
|
* @remove: called when device removed
|
|
|
|
* @driver: device driver structure
|
|
|
|
*
|
|
|
|
**/
|
|
|
|
struct mdev_driver {
|
2021-04-07 03:40:26 +08:00
|
|
|
int (*probe)(struct mdev_device *dev);
|
|
|
|
void (*remove)(struct mdev_device *dev);
|
2016-11-17 04:46:13 +08:00
|
|
|
struct device_driver driver;
|
|
|
|
};
|
|
|
|
|
2021-04-07 03:40:26 +08:00
|
|
|
static inline void *mdev_get_drvdata(struct mdev_device *mdev)
|
|
|
|
{
|
|
|
|
return mdev->driver_data;
|
|
|
|
}
|
|
|
|
static inline void mdev_set_drvdata(struct mdev_device *mdev, void *data)
|
|
|
|
{
|
|
|
|
mdev->driver_data = data;
|
|
|
|
}
|
|
|
|
static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
|
|
|
|
{
|
|
|
|
return &mdev->uuid;
|
|
|
|
}
|
2016-11-17 04:46:13 +08:00
|
|
|
|
|
|
|
extern struct bus_type mdev_bus_type;
|
|
|
|
|
2019-05-01 06:49:30 +08:00
|
|
|
int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops);
|
|
|
|
void mdev_unregister_device(struct device *dev);
|
2016-11-17 04:46:13 +08:00
|
|
|
|
2021-04-07 03:40:27 +08:00
|
|
|
int mdev_register_driver(struct mdev_driver *drv);
|
2019-05-01 06:49:30 +08:00
|
|
|
void mdev_unregister_driver(struct mdev_driver *drv);
|
2016-11-17 04:46:13 +08:00
|
|
|
|
2019-05-01 06:49:30 +08:00
|
|
|
struct device *mdev_parent_dev(struct mdev_device *mdev);
|
2021-04-07 03:40:26 +08:00
|
|
|
static inline struct device *mdev_dev(struct mdev_device *mdev)
|
|
|
|
{
|
|
|
|
return &mdev->dev;
|
|
|
|
}
|
|
|
|
static inline struct mdev_device *mdev_from_dev(struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->bus == &mdev_bus_type ? to_mdev_device(dev) : NULL;
|
|
|
|
}
|
2016-12-30 23:13:41 +08:00
|
|
|
|
2016-11-17 04:46:13 +08:00
|
|
|
#endif /* MDEV_H */
|