Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vfio: Accept vfio device file in the KVM facing kAPI

This makes the vfio file kAPIs to accept vfio device files, also a
preparation for vfio device cdev support.

For the kvm set with vfio device file, kvm pointer is stored in struct
vfio_device_file, and use kvm_ref_lock to protect kvm set and kvm
pointer usage within VFIO. This kvm pointer will be set to vfio_device
after device file is bound to iommufd in the cdev path.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Terrence Xu <terrence.xu@intel.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
Tested-by: Yanting Jiang <yanting.jiang@intel.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Tested-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Link: https://lore.kernel.org/r/20230718135551.6592-4-yi.l.liu@intel.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>

authored by

Yi Liu and committed by
Alex Williamson
34aeeecd b1a59be8

+38 -1
+3
drivers/vfio/vfio.h
··· 18 18 19 19 struct vfio_device_file { 20 20 struct vfio_device *device; 21 + 22 + spinlock_t kvm_ref_lock; /* protect kvm field */ 23 + struct kvm *kvm; 21 24 }; 22 25 23 26 void vfio_device_put_registration(struct vfio_device *device);
+35 -1
drivers/vfio/vfio_main.c
··· 429 429 return ERR_PTR(-ENOMEM); 430 430 431 431 df->device = device; 432 + spin_lock_init(&df->kvm_ref_lock); 432 433 433 434 return df; 434 435 } ··· 1191 1190 .mmap = vfio_device_fops_mmap, 1192 1191 }; 1193 1192 1193 + static struct vfio_device *vfio_device_from_file(struct file *file) 1194 + { 1195 + struct vfio_device_file *df = file->private_data; 1196 + 1197 + if (file->f_op != &vfio_device_fops) 1198 + return NULL; 1199 + return df->device; 1200 + } 1201 + 1194 1202 /** 1195 1203 * vfio_file_is_valid - True if the file is valid vfio file 1196 1204 * @file: VFIO group file or VFIO device file 1197 1205 */ 1198 1206 bool vfio_file_is_valid(struct file *file) 1199 1207 { 1200 - return vfio_group_from_file(file); 1208 + return vfio_group_from_file(file) || 1209 + vfio_device_from_file(file); 1201 1210 } 1202 1211 EXPORT_SYMBOL_GPL(vfio_file_is_valid); 1203 1212 ··· 1222 1211 */ 1223 1212 bool vfio_file_enforced_coherent(struct file *file) 1224 1213 { 1214 + struct vfio_device *device; 1225 1215 struct vfio_group *group; 1226 1216 1227 1217 group = vfio_group_from_file(file); 1228 1218 if (group) 1229 1219 return vfio_group_enforced_coherent(group); 1230 1220 1221 + device = vfio_device_from_file(file); 1222 + if (device) 1223 + return device_iommu_capable(device->dev, 1224 + IOMMU_CAP_ENFORCE_CACHE_COHERENCY); 1225 + 1231 1226 return true; 1232 1227 } 1233 1228 EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent); 1229 + 1230 + static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm) 1231 + { 1232 + struct vfio_device_file *df = file->private_data; 1233 + 1234 + /* 1235 + * The kvm is first recorded in the vfio_device_file, and will 1236 + * be propagated to vfio_device::kvm when the file is bound to 1237 + * iommufd successfully in the vfio device cdev path. 1238 + */ 1239 + spin_lock(&df->kvm_ref_lock); 1240 + df->kvm = kvm; 1241 + spin_unlock(&df->kvm_ref_lock); 1242 + } 1234 1243 1235 1244 /** 1236 1245 * vfio_file_set_kvm - Link a kvm with VFIO drivers ··· 1267 1236 group = vfio_group_from_file(file); 1268 1237 if (group) 1269 1238 vfio_group_set_kvm(group, kvm); 1239 + 1240 + if (vfio_device_from_file(file)) 1241 + vfio_device_file_set_kvm(file, kvm); 1270 1242 } 1271 1243 EXPORT_SYMBOL_GPL(vfio_file_set_kvm); 1272 1244