Skip to content

Commit 7bf70db

Browse files
committed
Merge tag 'vfio-v6.2-rc6' of https://github.com/awilliam/linux-vfio
Pull VFIO fixes from Alex Williamson: - Honor reserved regions when testing for IOMMU find grained super page support, avoiding a regression on s390 for a firmware device where the existence of the mapping, even if unused can trigger an error state. (Niklas Schnelle) - Fix a deadlock in releasing KVM references by using the alternate .release() rather than .destroy() callback for the kvm-vfio device. (Yi Liu) * tag 'vfio-v6.2-rc6' of https://github.com/awilliam/linux-vfio: kvm/vfio: Fix potential deadlock on vfio group_lock vfio/type1: Respect IOMMU reserved regions in vfio_test_domain_fgsp()
2 parents 9946f09 + 51cdc8b commit 7bf70db

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

drivers/vfio/vfio_iommu_type1.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,24 +1856,33 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
18561856
* significantly boosts non-hugetlbfs mappings and doesn't seem to hurt when
18571857
* hugetlbfs is in use.
18581858
*/
1859-
static void vfio_test_domain_fgsp(struct vfio_domain *domain)
1859+
static void vfio_test_domain_fgsp(struct vfio_domain *domain, struct list_head *regions)
18601860
{
1861-
struct page *pages;
18621861
int ret, order = get_order(PAGE_SIZE * 2);
1862+
struct vfio_iova *region;
1863+
struct page *pages;
1864+
dma_addr_t start;
18631865

18641866
pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
18651867
if (!pages)
18661868
return;
18671869

1868-
ret = iommu_map(domain->domain, 0, page_to_phys(pages), PAGE_SIZE * 2,
1869-
IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
1870-
if (!ret) {
1871-
size_t unmapped = iommu_unmap(domain->domain, 0, PAGE_SIZE);
1870+
list_for_each_entry(region, regions, list) {
1871+
start = ALIGN(region->start, PAGE_SIZE * 2);
1872+
if (start >= region->end || (region->end - start < PAGE_SIZE * 2))
1873+
continue;
18721874

1873-
if (unmapped == PAGE_SIZE)
1874-
iommu_unmap(domain->domain, PAGE_SIZE, PAGE_SIZE);
1875-
else
1876-
domain->fgsp = true;
1875+
ret = iommu_map(domain->domain, start, page_to_phys(pages), PAGE_SIZE * 2,
1876+
IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
1877+
if (!ret) {
1878+
size_t unmapped = iommu_unmap(domain->domain, start, PAGE_SIZE);
1879+
1880+
if (unmapped == PAGE_SIZE)
1881+
iommu_unmap(domain->domain, start + PAGE_SIZE, PAGE_SIZE);
1882+
else
1883+
domain->fgsp = true;
1884+
}
1885+
break;
18771886
}
18781887

18791888
__free_pages(pages, order);
@@ -2326,7 +2335,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
23262335
}
23272336
}
23282337

2329-
vfio_test_domain_fgsp(domain);
2338+
vfio_test_domain_fgsp(domain, &iova_copy);
23302339

23312340
/* replay mappings on new domains */
23322341
ret = vfio_iommu_replay(iommu, domain);

virt/kvm/vfio.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ static int kvm_vfio_has_attr(struct kvm_device *dev,
336336
return -ENXIO;
337337
}
338338

339-
static void kvm_vfio_destroy(struct kvm_device *dev)
339+
static void kvm_vfio_release(struct kvm_device *dev)
340340
{
341341
struct kvm_vfio *kv = dev->private;
342342
struct kvm_vfio_group *kvg, *tmp;
@@ -355,15 +355,15 @@ static void kvm_vfio_destroy(struct kvm_device *dev)
355355
kvm_vfio_update_coherency(dev);
356356

357357
kfree(kv);
358-
kfree(dev); /* alloc by kvm_ioctl_create_device, free by .destroy */
358+
kfree(dev); /* alloc by kvm_ioctl_create_device, free by .release */
359359
}
360360

361361
static int kvm_vfio_create(struct kvm_device *dev, u32 type);
362362

363363
static struct kvm_device_ops kvm_vfio_ops = {
364364
.name = "kvm-vfio",
365365
.create = kvm_vfio_create,
366-
.destroy = kvm_vfio_destroy,
366+
.release = kvm_vfio_release,
367367
.set_attr = kvm_vfio_set_attr,
368368
.has_attr = kvm_vfio_has_attr,
369369
};

0 commit comments

Comments
 (0)