| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * VFIO API definition |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2012 Red Hat, Inc. All rights reserved. |
|---|
| 5 | 6 | * Author: Alex Williamson <alex.williamson@redhat.com> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 7 | */ |
|---|
| 11 | 8 | #ifndef VFIO_H |
|---|
| 12 | 9 | #define VFIO_H |
|---|
| .. | .. |
|---|
| 17 | 14 | #include <linux/workqueue.h> |
|---|
| 18 | 15 | #include <linux/poll.h> |
|---|
| 19 | 16 | #include <uapi/linux/vfio.h> |
|---|
| 17 | + |
|---|
| 18 | +struct vfio_device { |
|---|
| 19 | + struct device *dev; |
|---|
| 20 | + const struct vfio_device_ops *ops; |
|---|
| 21 | + struct vfio_group *group; |
|---|
| 22 | + |
|---|
| 23 | + /* Members below here are private, not for driver use */ |
|---|
| 24 | + refcount_t refcount; |
|---|
| 25 | + struct completion comp; |
|---|
| 26 | + struct list_head group_next; |
|---|
| 27 | + void *device_data; |
|---|
| 28 | +}; |
|---|
| 20 | 29 | |
|---|
| 21 | 30 | /** |
|---|
| 22 | 31 | * struct vfio_device_ops - VFIO bus driver device callbacks |
|---|
| .. | .. |
|---|
| 29 | 38 | * operations documented below |
|---|
| 30 | 39 | * @mmap: Perform mmap(2) on a region of the device file descriptor |
|---|
| 31 | 40 | * @request: Request for the bus driver to release the device |
|---|
| 41 | + * @match: Optional device name match callback (return: 0 for no-match, >0 for |
|---|
| 42 | + * match, -errno for abort (ex. match with insufficient or incorrect |
|---|
| 43 | + * additional args) |
|---|
| 32 | 44 | */ |
|---|
| 33 | 45 | struct vfio_device_ops { |
|---|
| 34 | 46 | char *name; |
|---|
| .. | .. |
|---|
| 42 | 54 | unsigned long arg); |
|---|
| 43 | 55 | int (*mmap)(void *device_data, struct vm_area_struct *vma); |
|---|
| 44 | 56 | void (*request)(void *device_data, unsigned int count); |
|---|
| 57 | + int (*match)(void *device_data, char *buf); |
|---|
| 45 | 58 | }; |
|---|
| 46 | 59 | |
|---|
| 47 | 60 | extern struct iommu_group *vfio_iommu_group_get(struct device *dev); |
|---|
| 48 | 61 | extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev); |
|---|
| 49 | 62 | |
|---|
| 63 | +void vfio_init_group_dev(struct vfio_device *device, struct device *dev, |
|---|
| 64 | + const struct vfio_device_ops *ops, void *device_data); |
|---|
| 65 | +int vfio_register_group_dev(struct vfio_device *device); |
|---|
| 50 | 66 | extern int vfio_add_group_dev(struct device *dev, |
|---|
| 51 | 67 | const struct vfio_device_ops *ops, |
|---|
| 52 | 68 | void *device_data); |
|---|
| 53 | 69 | |
|---|
| 54 | 70 | extern void *vfio_del_group_dev(struct device *dev); |
|---|
| 71 | +void vfio_unregister_group_dev(struct vfio_device *device); |
|---|
| 55 | 72 | extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); |
|---|
| 56 | 73 | extern void vfio_device_put(struct vfio_device *device); |
|---|
| 57 | 74 | extern void *vfio_device_data(struct vfio_device *device); |
|---|
| .. | .. |
|---|
| 75 | 92 | struct iommu_group *group); |
|---|
| 76 | 93 | void (*detach_group)(void *iommu_data, |
|---|
| 77 | 94 | struct iommu_group *group); |
|---|
| 78 | | - int (*pin_pages)(void *iommu_data, unsigned long *user_pfn, |
|---|
| 95 | + int (*pin_pages)(void *iommu_data, |
|---|
| 96 | + struct iommu_group *group, |
|---|
| 97 | + unsigned long *user_pfn, |
|---|
| 79 | 98 | int npage, int prot, |
|---|
| 80 | 99 | unsigned long *phys_pfn); |
|---|
| 81 | 100 | int (*unpin_pages)(void *iommu_data, |
|---|
| .. | .. |
|---|
| 85 | 104 | struct notifier_block *nb); |
|---|
| 86 | 105 | int (*unregister_notifier)(void *iommu_data, |
|---|
| 87 | 106 | struct notifier_block *nb); |
|---|
| 107 | + int (*dma_rw)(void *iommu_data, dma_addr_t user_iova, |
|---|
| 108 | + void *data, size_t count, bool write); |
|---|
| 88 | 109 | }; |
|---|
| 89 | 110 | |
|---|
| 90 | 111 | extern int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops); |
|---|
| .. | .. |
|---|
| 97 | 118 | */ |
|---|
| 98 | 119 | extern struct vfio_group *vfio_group_get_external_user(struct file *filep); |
|---|
| 99 | 120 | extern void vfio_group_put_external_user(struct vfio_group *group); |
|---|
| 121 | +extern struct vfio_group *vfio_group_get_external_user_from_dev(struct device |
|---|
| 122 | + *dev); |
|---|
| 100 | 123 | extern bool vfio_external_group_match_file(struct vfio_group *group, |
|---|
| 101 | 124 | struct file *filep); |
|---|
| 102 | 125 | extern int vfio_external_user_iommu_id(struct vfio_group *group); |
|---|
| .. | .. |
|---|
| 110 | 133 | extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn, |
|---|
| 111 | 134 | int npage); |
|---|
| 112 | 135 | |
|---|
| 136 | +extern int vfio_group_pin_pages(struct vfio_group *group, |
|---|
| 137 | + unsigned long *user_iova_pfn, int npage, |
|---|
| 138 | + int prot, unsigned long *phys_pfn); |
|---|
| 139 | +extern int vfio_group_unpin_pages(struct vfio_group *group, |
|---|
| 140 | + unsigned long *user_iova_pfn, int npage); |
|---|
| 141 | + |
|---|
| 142 | +extern int vfio_dma_rw(struct vfio_group *group, dma_addr_t user_iova, |
|---|
| 143 | + void *data, size_t len, bool write); |
|---|
| 144 | + |
|---|
| 113 | 145 | /* each type has independent events */ |
|---|
| 114 | 146 | enum vfio_notify_type { |
|---|
| 115 | 147 | VFIO_IOMMU_NOTIFY = 0, |
|---|