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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfio-v4.14-rc1' of git://github.com/awilliam/linux-vfio

Pull VFIO updates from Alex Williamson:

- Base MSI remapping on either IOMMU domain or IRQ domain support
(Robin Murphy)

- Prioritize hardware MSI regions over software defined regions (Robin
Murphy)

- Fix no-iommu reference counting (Eric Auger)

- Stall removing last device from group for container cleanup (Alex
Williamson)

- Constify amba_id (Arvind Yadav)

* tag 'vfio-v4.14-rc1' of git://github.com/awilliam/linux-vfio:
vfio: platform: constify amba_id
vfio: Stall vfio_del_group_dev() for container group detach
vfio: fix noiommu vfio_iommu_group_get reference count
vfio/type1: Give hardware MSI regions precedence
vfio/type1: Cope with hardware MSI reserved regions

+36 -7
+1 -1
drivers/vfio/platform/vfio_amba.c
··· 93 93 return -EINVAL; 94 94 } 95 95 96 - static struct amba_id pl330_ids[] = { 96 + static const struct amba_id pl330_ids[] = { 97 97 { 0, 0 }, 98 98 }; 99 99
+23 -2
drivers/vfio/vfio.c
··· 85 85 struct list_head unbound_list; 86 86 struct mutex unbound_lock; 87 87 atomic_t opened; 88 + wait_queue_head_t container_q; 88 89 bool noiommu; 89 90 struct kvm *kvm; 90 91 struct blocking_notifier_head notifier; ··· 139 138 iommu_group_set_name(group, "vfio-noiommu"); 140 139 iommu_group_set_iommudata(group, &noiommu, NULL); 141 140 ret = iommu_group_add_device(group, dev); 142 - iommu_group_put(group); 143 - if (ret) 141 + if (ret) { 142 + iommu_group_put(group); 144 143 return NULL; 144 + } 145 145 146 146 /* 147 147 * Where to taint? At this point we've added an IOMMU group for a ··· 339 337 mutex_init(&group->unbound_lock); 340 338 atomic_set(&group->container_users, 0); 341 339 atomic_set(&group->opened, 0); 340 + init_waitqueue_head(&group->container_q); 342 341 group->iommu_group = iommu_group; 343 342 #ifdef CONFIG_VFIO_NOIOMMU 344 343 group->noiommu = (iommu_group_get_iommudata(iommu_group) == &noiommu); ··· 996 993 } 997 994 } while (ret <= 0); 998 995 996 + /* 997 + * In order to support multiple devices per group, devices can be 998 + * plucked from the group while other devices in the group are still 999 + * in use. The container persists with this group and those remaining 1000 + * devices still attached. If the user creates an isolation violation 1001 + * by binding this device to another driver while the group is still in 1002 + * use, that's their fault. However, in the case of removing the last, 1003 + * or potentially the only, device in the group there can be no other 1004 + * in-use devices in the group. The user has done their due diligence 1005 + * and we should lay no claims to those devices. In order to do that, 1006 + * we need to make sure the group is detached from the container. 1007 + * Without this stall, we're potentially racing with a user process 1008 + * that may attempt to immediately bind this device to another driver. 1009 + */ 1010 + if (list_empty(&group->device_list)) 1011 + wait_event(group->container_q, !group->container); 1012 + 999 1013 vfio_group_put(group); 1000 1014 1001 1015 return device_data; ··· 1318 1298 group->iommu_group); 1319 1299 1320 1300 group->container = NULL; 1301 + wake_up(&group->container_q); 1321 1302 list_del(&group->container_next); 1322 1303 1323 1304 /* Detaching the last group deprivileges a container, remove iommu */
+12 -4
drivers/vfio/vfio_iommu_type1.c
··· 1169 1169 INIT_LIST_HEAD(&group_resv_regions); 1170 1170 iommu_get_group_resv_regions(group, &group_resv_regions); 1171 1171 list_for_each_entry(region, &group_resv_regions, list) { 1172 + /* 1173 + * The presence of any 'real' MSI regions should take 1174 + * precedence over the software-managed one if the 1175 + * IOMMU driver happens to advertise both types. 1176 + */ 1177 + if (region->type == IOMMU_RESV_MSI) { 1178 + ret = false; 1179 + break; 1180 + } 1181 + 1172 1182 if (region->type == IOMMU_RESV_SW_MSI) { 1173 1183 *base = region->start; 1174 1184 ret = true; 1175 - goto out; 1176 1185 } 1177 1186 } 1178 - out: 1179 1187 list_for_each_entry_safe(region, next, &group_resv_regions, list) 1180 1188 kfree(region); 1181 1189 return ret; ··· 1273 1265 INIT_LIST_HEAD(&domain->group_list); 1274 1266 list_add(&group->next, &domain->group_list); 1275 1267 1276 - msi_remap = resv_msi ? irq_domain_check_msi_remap() : 1277 - iommu_capable(bus, IOMMU_CAP_INTR_REMAP); 1268 + msi_remap = irq_domain_check_msi_remap() || 1269 + iommu_capable(bus, IOMMU_CAP_INTR_REMAP); 1278 1270 1279 1271 if (!allow_unsafe_interrupts && !msi_remap) { 1280 1272 pr_warn("%s: No interrupt remapping support. Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n",