Skip to content

Commit 29c902d

Browse files
author
Herton R. Krzesinski
committed
Merge: vfio: Fix sr-iov mdev regression, PCI reset regression, complete baseline migration support
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1816 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2158449 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2155664 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2158549 Upstream Status: mainline + RHEL-only Testing: GPU assignment, PF/VF NIC assignment, GVT-g mdev assignment - A fix in RHEL-only code where we were previously overriding the bus pointer before jumping out to upstream code and now need to override the iommu_group pointer instead. - Fix an upstream regression where we're not performing a PCI secondary bus reset when the VM is shutdown uncleanly. - Include feature to report the migration data size, which is necessary for a baseline migration implementation in userspace. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Approved-by: Cédric Le Goater <clg@redhat.com> Approved-by: Cornelia Huck <cohuck@redhat.com> Approved-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
2 parents 43ad2cf + 9e43e61 commit 29c902d

File tree

5 files changed

+109
-27
lines changed

5 files changed

+109
-27
lines changed

drivers/vfio/pci/vfio_pci_core.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,7 +1865,8 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
18651865

18661866
if (vdev->vdev.mig_ops) {
18671867
if (!(vdev->vdev.mig_ops->migration_get_state &&
1868-
vdev->vdev.mig_ops->migration_set_state) ||
1868+
vdev->vdev.mig_ops->migration_set_state &&
1869+
vdev->vdev.mig_ops->migration_get_data_size) ||
18691870
!(vdev->vdev.migration_flags & VFIO_MIGRATION_STOP_COPY))
18701871
return -EINVAL;
18711872
}
@@ -2208,12 +2209,12 @@ static bool vfio_pci_dev_set_needs_reset(struct vfio_device_set *dev_set)
22082209
struct vfio_pci_core_device *cur;
22092210
bool needs_reset = false;
22102211

2211-
list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list) {
2212-
/* No VFIO device in the set can have an open device FD */
2213-
if (cur->vdev.open_count)
2214-
return false;
2212+
/* No other VFIO device in the set can be open. */
2213+
if (vfio_device_set_open_count(dev_set) > 1)
2214+
return false;
2215+
2216+
list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list)
22152217
needs_reset |= cur->needs_reset;
2216-
}
22172218
return needs_reset;
22182219
}
22192220

drivers/vfio/vfio_iommu_type1.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2305,7 +2305,14 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
23052305
&iommu_device,
23062306
vfio_mdev_iommu_device);
23072307
if (!ret && iommu_device) {
2308-
bus = iommu_device->bus;
2308+
/*
2309+
* Replace iommu_group with that of the IOMMU
2310+
* backing device for all remaining operations,
2311+
* ie. domain_alloc, reserved regions, and
2312+
* capability checks. Be careful this is
2313+
* appropriate for all new uses.
2314+
*/
2315+
iommu_group = iommu_device->iommu_group;
23092316
goto rhel_mdev_iommu_device;
23102317
}
23112318
}

drivers/vfio/vfio_main.c

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,19 @@ static void vfio_container_put(struct vfio_container *container)
302302
kref_put(&container->kref, vfio_container_release);
303303
}
304304

305+
unsigned int vfio_device_set_open_count(struct vfio_device_set *dev_set)
306+
{
307+
struct vfio_device *cur;
308+
unsigned int open_count = 0;
309+
310+
lockdep_assert_held(&dev_set->lock);
311+
312+
list_for_each_entry(cur, &dev_set->device_list, dev_set_list)
313+
open_count += cur->open_count;
314+
return open_count;
315+
}
316+
EXPORT_SYMBOL_GPL(vfio_device_set_open_count);
317+
305318
/*
306319
* Group objects - create, release, get, put, search
307320
*/
@@ -1085,9 +1098,28 @@ static void vfio_device_unassign_container(struct vfio_device *device)
10851098
up_write(&device->group->group_rwsem);
10861099
}
10871100

1101+
static void vfio_device_container_register(struct vfio_device *device)
1102+
{
1103+
struct vfio_iommu_driver *iommu_driver =
1104+
device->group->container->iommu_driver;
1105+
1106+
if (iommu_driver && iommu_driver->ops->register_device)
1107+
iommu_driver->ops->register_device(
1108+
device->group->container->iommu_data, device);
1109+
}
1110+
1111+
static void vfio_device_container_unregister(struct vfio_device *device)
1112+
{
1113+
struct vfio_iommu_driver *iommu_driver =
1114+
device->group->container->iommu_driver;
1115+
1116+
if (iommu_driver && iommu_driver->ops->unregister_device)
1117+
iommu_driver->ops->unregister_device(
1118+
device->group->container->iommu_data, device);
1119+
}
1120+
10881121
static struct file *vfio_device_open(struct vfio_device *device)
10891122
{
1090-
struct vfio_iommu_driver *iommu_driver;
10911123
struct file *filep;
10921124
int ret;
10931125

@@ -1118,12 +1150,7 @@ static struct file *vfio_device_open(struct vfio_device *device)
11181150
if (ret)
11191151
goto err_undo_count;
11201152
}
1121-
1122-
iommu_driver = device->group->container->iommu_driver;
1123-
if (iommu_driver && iommu_driver->ops->register_device)
1124-
iommu_driver->ops->register_device(
1125-
device->group->container->iommu_data, device);
1126-
1153+
vfio_device_container_register(device);
11271154
up_read(&device->group->group_rwsem);
11281155
}
11291156
mutex_unlock(&device->dev_set->lock);
@@ -1158,13 +1185,11 @@ static struct file *vfio_device_open(struct vfio_device *device)
11581185
err_close_device:
11591186
mutex_lock(&device->dev_set->lock);
11601187
down_read(&device->group->group_rwsem);
1161-
if (device->open_count == 1 && device->ops->close_device) {
1162-
device->ops->close_device(device);
1188+
if (device->open_count == 1) {
1189+
if (device->ops->close_device)
1190+
device->ops->close_device(device);
11631191

1164-
iommu_driver = device->group->container->iommu_driver;
1165-
if (iommu_driver && iommu_driver->ops->unregister_device)
1166-
iommu_driver->ops->unregister_device(
1167-
device->group->container->iommu_data, device);
1192+
vfio_device_container_unregister(device);
11681193
}
11691194
err_undo_count:
11701195
up_read(&device->group->group_rwsem);
@@ -1360,18 +1385,16 @@ static const struct file_operations vfio_group_fops = {
13601385
static int vfio_device_fops_release(struct inode *inode, struct file *filep)
13611386
{
13621387
struct vfio_device *device = filep->private_data;
1363-
struct vfio_iommu_driver *iommu_driver;
13641388

13651389
mutex_lock(&device->dev_set->lock);
13661390
vfio_assert_device_open(device);
13671391
down_read(&device->group->group_rwsem);
1368-
if (device->open_count == 1 && device->ops->close_device)
1369-
device->ops->close_device(device);
1392+
if (device->open_count == 1) {
1393+
if (device->ops->close_device)
1394+
device->ops->close_device(device);
13701395

1371-
iommu_driver = device->group->container->iommu_driver;
1372-
if (iommu_driver && iommu_driver->ops->unregister_device)
1373-
iommu_driver->ops->unregister_device(
1374-
device->group->container->iommu_data, device);
1396+
vfio_device_container_unregister(device);
1397+
}
13751398
up_read(&device->group->group_rwsem);
13761399
device->open_count--;
13771400
if (device->open_count == 0)
@@ -1607,6 +1630,34 @@ vfio_ioctl_device_feature_mig_device_state(struct vfio_device *device,
16071630
return 0;
16081631
}
16091632

1633+
static int
1634+
vfio_ioctl_device_feature_migration_data_size(struct vfio_device *device,
1635+
u32 flags, void __user *arg,
1636+
size_t argsz)
1637+
{
1638+
struct vfio_device_feature_mig_data_size data_size = {};
1639+
unsigned long stop_copy_length;
1640+
int ret;
1641+
1642+
if (!device->mig_ops)
1643+
return -ENOTTY;
1644+
1645+
ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_GET,
1646+
sizeof(data_size));
1647+
if (ret != 1)
1648+
return ret;
1649+
1650+
ret = device->mig_ops->migration_get_data_size(device, &stop_copy_length);
1651+
if (ret)
1652+
return ret;
1653+
1654+
data_size.stop_copy_length = stop_copy_length;
1655+
if (copy_to_user(arg, &data_size, sizeof(data_size)))
1656+
return -EFAULT;
1657+
1658+
return 0;
1659+
}
1660+
16101661
static int vfio_ioctl_device_feature_migration(struct vfio_device *device,
16111662
u32 flags, void __user *arg,
16121663
size_t argsz)
@@ -1661,6 +1712,10 @@ static int vfio_ioctl_device_feature(struct vfio_device *device,
16611712
return vfio_ioctl_device_feature_mig_device_state(
16621713
device, feature.flags, arg->data,
16631714
feature.argsz - minsz);
1715+
case VFIO_DEVICE_FEATURE_MIG_DATA_SIZE:
1716+
return vfio_ioctl_device_feature_migration_data_size(
1717+
device, feature.flags, arg->data,
1718+
feature.argsz - minsz);
16641719
default:
16651720
if (unlikely(!device->ops->device_feature))
16661721
return -EINVAL;

include/linux/vfio.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,18 @@ struct vfio_device_ops {
9999
* @migration_get_state: Optional callback to get the migration state for
100100
* devices that support migration. It's mandatory for
101101
* VFIO_DEVICE_FEATURE_MIGRATION migration support.
102+
* @migration_get_data_size: Optional callback to get the estimated data
103+
* length that will be required to complete stop copy. It's mandatory for
104+
* VFIO_DEVICE_FEATURE_MIGRATION migration support.
102105
*/
103106
struct vfio_migration_ops {
104107
struct file *(*migration_set_state)(
105108
struct vfio_device *device,
106109
enum vfio_device_mig_state new_state);
107110
int (*migration_get_state)(struct vfio_device *device,
108111
enum vfio_device_mig_state *curr_state);
112+
int (*migration_get_data_size)(struct vfio_device *device,
113+
unsigned long *stop_copy_length);
109114
};
110115

111116
/**
@@ -145,6 +150,7 @@ int vfio_register_emulated_iommu_dev(struct vfio_device *device);
145150
void vfio_unregister_group_dev(struct vfio_device *device);
146151

147152
int vfio_assign_device_set(struct vfio_device *device, void *set_id);
153+
unsigned int vfio_device_set_open_count(struct vfio_device_set *dev_set);
148154

149155
int vfio_mig_get_next_state(struct vfio_device *device,
150156
enum vfio_device_mig_state cur_fsm,

include/uapi/linux/vfio.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,19 @@ enum vfio_device_mig_state {
986986
VFIO_DEVICE_STATE_RUNNING_P2P = 5,
987987
};
988988

989+
/*
990+
* Upon VFIO_DEVICE_FEATURE_GET read back the estimated data length that will
991+
* be required to complete stop copy.
992+
*
993+
* Note: Can be called on each device state.
994+
*/
995+
996+
struct vfio_device_feature_mig_data_size {
997+
__aligned_u64 stop_copy_length;
998+
};
999+
1000+
#define VFIO_DEVICE_FEATURE_MIG_DATA_SIZE 9
1001+
9891002
/* -------- API for Type1 VFIO IOMMU -------- */
9901003

9911004
/**

0 commit comments

Comments
 (0)