Skip to content

Commit 73b0565

Browse files
jgunthorpeawilliam
authored andcommitted
kvm/vfio: Move KVM_DEV_VFIO_GROUP_* ioctls into functions
To make it easier to read and change in following patches. Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Cornelia Huck <[email protected]> Reviewed-by: Yi Liu <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent dc15f82 commit 73b0565

File tree

1 file changed

+124
-101
lines changed

1 file changed

+124
-101
lines changed

virt/kvm/vfio.c

Lines changed: 124 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -181,149 +181,171 @@ static void kvm_vfio_update_coherency(struct kvm_device *dev)
181181
mutex_unlock(&kv->lock);
182182
}
183183

184-
static int kvm_vfio_set_group(struct kvm_device *dev, long attr, u64 arg)
184+
static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
185185
{
186186
struct kvm_vfio *kv = dev->private;
187187
struct vfio_group *vfio_group;
188188
struct kvm_vfio_group *kvg;
189-
int32_t __user *argp = (int32_t __user *)(unsigned long)arg;
190189
struct fd f;
191-
int32_t fd;
192190
int ret;
193191

194-
switch (attr) {
195-
case KVM_DEV_VFIO_GROUP_ADD:
196-
if (get_user(fd, argp))
197-
return -EFAULT;
198-
199-
f = fdget(fd);
200-
if (!f.file)
201-
return -EBADF;
202-
203-
vfio_group = kvm_vfio_group_get_external_user(f.file);
204-
fdput(f);
192+
f = fdget(fd);
193+
if (!f.file)
194+
return -EBADF;
205195

206-
if (IS_ERR(vfio_group))
207-
return PTR_ERR(vfio_group);
196+
vfio_group = kvm_vfio_group_get_external_user(f.file);
197+
fdput(f);
208198

209-
mutex_lock(&kv->lock);
199+
if (IS_ERR(vfio_group))
200+
return PTR_ERR(vfio_group);
210201

211-
list_for_each_entry(kvg, &kv->group_list, node) {
212-
if (kvg->vfio_group == vfio_group) {
213-
mutex_unlock(&kv->lock);
214-
kvm_vfio_group_put_external_user(vfio_group);
215-
return -EEXIST;
216-
}
217-
}
202+
mutex_lock(&kv->lock);
218203

219-
kvg = kzalloc(sizeof(*kvg), GFP_KERNEL_ACCOUNT);
220-
if (!kvg) {
221-
mutex_unlock(&kv->lock);
222-
kvm_vfio_group_put_external_user(vfio_group);
223-
return -ENOMEM;
204+
list_for_each_entry(kvg, &kv->group_list, node) {
205+
if (kvg->vfio_group == vfio_group) {
206+
ret = -EEXIST;
207+
goto err_unlock;
224208
}
209+
}
225210

226-
list_add_tail(&kvg->node, &kv->group_list);
227-
kvg->vfio_group = vfio_group;
211+
kvg = kzalloc(sizeof(*kvg), GFP_KERNEL_ACCOUNT);
212+
if (!kvg) {
213+
ret = -ENOMEM;
214+
goto err_unlock;
215+
}
228216

229-
kvm_arch_start_assignment(dev->kvm);
217+
list_add_tail(&kvg->node, &kv->group_list);
218+
kvg->vfio_group = vfio_group;
230219

231-
mutex_unlock(&kv->lock);
220+
kvm_arch_start_assignment(dev->kvm);
232221

233-
kvm_vfio_group_set_kvm(vfio_group, dev->kvm);
222+
mutex_unlock(&kv->lock);
234223

235-
kvm_vfio_update_coherency(dev);
224+
kvm_vfio_group_set_kvm(vfio_group, dev->kvm);
225+
kvm_vfio_update_coherency(dev);
236226

237-
return 0;
227+
return 0;
228+
err_unlock:
229+
mutex_unlock(&kv->lock);
230+
kvm_vfio_group_put_external_user(vfio_group);
231+
return ret;
232+
}
238233

239-
case KVM_DEV_VFIO_GROUP_DEL:
240-
if (get_user(fd, argp))
241-
return -EFAULT;
234+
static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd)
235+
{
236+
struct kvm_vfio *kv = dev->private;
237+
struct kvm_vfio_group *kvg;
238+
struct fd f;
239+
int ret;
242240

243-
f = fdget(fd);
244-
if (!f.file)
245-
return -EBADF;
241+
f = fdget(fd);
242+
if (!f.file)
243+
return -EBADF;
246244

247-
ret = -ENOENT;
245+
ret = -ENOENT;
248246

249-
mutex_lock(&kv->lock);
247+
mutex_lock(&kv->lock);
250248

251-
list_for_each_entry(kvg, &kv->group_list, node) {
252-
if (!kvm_vfio_external_group_match_file(kvg->vfio_group,
253-
f.file))
254-
continue;
249+
list_for_each_entry(kvg, &kv->group_list, node) {
250+
if (!kvm_vfio_external_group_match_file(kvg->vfio_group,
251+
f.file))
252+
continue;
255253

256-
list_del(&kvg->node);
257-
kvm_arch_end_assignment(dev->kvm);
254+
list_del(&kvg->node);
255+
kvm_arch_end_assignment(dev->kvm);
258256
#ifdef CONFIG_SPAPR_TCE_IOMMU
259-
kvm_spapr_tce_release_vfio_group(dev->kvm,
260-
kvg->vfio_group);
257+
kvm_spapr_tce_release_vfio_group(dev->kvm, kvg->vfio_group);
261258
#endif
262-
kvm_vfio_group_set_kvm(kvg->vfio_group, NULL);
263-
kvm_vfio_group_put_external_user(kvg->vfio_group);
264-
kfree(kvg);
265-
ret = 0;
266-
break;
267-
}
259+
kvm_vfio_group_set_kvm(kvg->vfio_group, NULL);
260+
kvm_vfio_group_put_external_user(kvg->vfio_group);
261+
kfree(kvg);
262+
ret = 0;
263+
break;
264+
}
268265

269-
mutex_unlock(&kv->lock);
266+
mutex_unlock(&kv->lock);
270267

271-
fdput(f);
268+
fdput(f);
272269

273-
kvm_vfio_update_coherency(dev);
270+
kvm_vfio_update_coherency(dev);
274271

275-
return ret;
272+
return ret;
273+
}
276274

277275
#ifdef CONFIG_SPAPR_TCE_IOMMU
278-
case KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE: {
279-
struct kvm_vfio_spapr_tce param;
280-
struct kvm_vfio *kv = dev->private;
281-
struct vfio_group *vfio_group;
282-
struct kvm_vfio_group *kvg;
283-
struct fd f;
284-
struct iommu_group *grp;
285-
286-
if (copy_from_user(&param, (void __user *)arg,
287-
sizeof(struct kvm_vfio_spapr_tce)))
288-
return -EFAULT;
276+
static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
277+
void __user *arg)
278+
{
279+
struct kvm_vfio_spapr_tce param;
280+
struct kvm_vfio *kv = dev->private;
281+
struct vfio_group *vfio_group;
282+
struct kvm_vfio_group *kvg;
283+
struct fd f;
284+
struct iommu_group *grp;
285+
int ret;
289286

290-
f = fdget(param.groupfd);
291-
if (!f.file)
292-
return -EBADF;
287+
if (copy_from_user(&param, arg, sizeof(struct kvm_vfio_spapr_tce)))
288+
return -EFAULT;
293289

294-
vfio_group = kvm_vfio_group_get_external_user(f.file);
295-
fdput(f);
290+
f = fdget(param.groupfd);
291+
if (!f.file)
292+
return -EBADF;
296293

297-
if (IS_ERR(vfio_group))
298-
return PTR_ERR(vfio_group);
294+
vfio_group = kvm_vfio_group_get_external_user(f.file);
295+
fdput(f);
299296

300-
grp = kvm_vfio_group_get_iommu_group(vfio_group);
301-
if (WARN_ON_ONCE(!grp)) {
302-
kvm_vfio_group_put_external_user(vfio_group);
303-
return -EIO;
304-
}
297+
if (IS_ERR(vfio_group))
298+
return PTR_ERR(vfio_group);
305299

306-
ret = -ENOENT;
300+
grp = kvm_vfio_group_get_iommu_group(vfio_group);
301+
if (WARN_ON_ONCE(!grp)) {
302+
ret = -EIO;
303+
goto err_put_external;
304+
}
307305

308-
mutex_lock(&kv->lock);
306+
ret = -ENOENT;
309307

310-
list_for_each_entry(kvg, &kv->group_list, node) {
311-
if (kvg->vfio_group != vfio_group)
312-
continue;
308+
mutex_lock(&kv->lock);
313309

314-
ret = kvm_spapr_tce_attach_iommu_group(dev->kvm,
315-
param.tablefd, grp);
316-
break;
317-
}
310+
list_for_each_entry(kvg, &kv->group_list, node) {
311+
if (kvg->vfio_group != vfio_group)
312+
continue;
318313

319-
mutex_unlock(&kv->lock);
314+
ret = kvm_spapr_tce_attach_iommu_group(dev->kvm, param.tablefd,
315+
grp);
316+
break;
317+
}
320318

321-
iommu_group_put(grp);
322-
kvm_vfio_group_put_external_user(vfio_group);
319+
mutex_unlock(&kv->lock);
323320

324-
return ret;
325-
}
326-
#endif /* CONFIG_SPAPR_TCE_IOMMU */
321+
iommu_group_put(grp);
322+
err_put_external:
323+
kvm_vfio_group_put_external_user(vfio_group);
324+
return ret;
325+
}
326+
#endif
327+
328+
static int kvm_vfio_set_group(struct kvm_device *dev, long attr,
329+
void __user *arg)
330+
{
331+
int32_t __user *argp = arg;
332+
int32_t fd;
333+
334+
switch (attr) {
335+
case KVM_DEV_VFIO_GROUP_ADD:
336+
if (get_user(fd, argp))
337+
return -EFAULT;
338+
return kvm_vfio_group_add(dev, fd);
339+
340+
case KVM_DEV_VFIO_GROUP_DEL:
341+
if (get_user(fd, argp))
342+
return -EFAULT;
343+
return kvm_vfio_group_del(dev, fd);
344+
345+
#ifdef CONFIG_SPAPR_TCE_IOMMU
346+
case KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE:
347+
return kvm_vfio_group_set_spapr_tce(dev, arg);
348+
#endif
327349
}
328350

329351
return -ENXIO;
@@ -334,7 +356,8 @@ static int kvm_vfio_set_attr(struct kvm_device *dev,
334356
{
335357
switch (attr->group) {
336358
case KVM_DEV_VFIO_GROUP:
337-
return kvm_vfio_set_group(dev, attr->attr, attr->addr);
359+
return kvm_vfio_set_group(dev, attr->attr,
360+
u64_to_user_ptr(attr->addr));
338361
}
339362

340363
return -ENXIO;

0 commit comments

Comments
 (0)