diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 92c5d5ef8d00..170a7005f0bc 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -866,7 +866,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev, ioasid_t pasid, { /* * iommufd_hw_pagetable_attach() is called by - * iommufd_hw_pagetable_alloc() in immediate attachment mode, same as + * iommufd_hwpt_paging_alloc() in immediate attachment mode, same as * iommufd_device_do_attach(). So if we are in this mode then we prefer * to use the immediate_attach path as it supports drivers that can't * directly allocate a domain. diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c index f1e686b3a265..710eef0b6004 100644 --- a/drivers/iommu/iommufd/eventq.c +++ b/drivers/iommu/iommufd/eventq.c @@ -187,9 +187,10 @@ static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *b mutex_lock(&fault->mutex); while (count > done) { - rc = copy_from_user(&response, buf + done, response_size); - if (rc) + if (copy_from_user(&response, buf + done, response_size)) { + rc = -EFAULT; break; + } static_assert((int)IOMMUFD_PAGE_RESP_SUCCESS == (int)IOMMU_PAGE_RESP_SUCCESS); diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c index ee003bb2f647..24d4917105d9 100644 --- a/drivers/iommu/iommufd/io_pagetable.c +++ b/drivers/iommu/iommufd/io_pagetable.c @@ -814,6 +814,16 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start, unmapped_bytes += area_last - area_first + 1; down_write(&iopt->iova_rwsem); + + /* + * After releasing the iova_rwsem concurrent allocation could + * place new areas at IOVAs we have already unmapped. Keep + * moving the start of the search forward to ignore the area + * already unmapped. + */ + if (area_last >= last) + break; + start = area_last + 1; } out_unlock_iova: diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h index 73e73e1ec158..52b78cbcc920 100644 --- a/drivers/iommu/iommufd/iommufd_test.h +++ b/drivers/iommu/iommufd/iommufd_test.h @@ -36,7 +36,6 @@ enum { enum { MOCK_IOMMUPT_DEFAULT = 0, MOCK_IOMMUPT_HUGE, - MOCK_IOMMUPT_AMDV1, }; /* These values are true for MOCK_IOMMUPT_DEFAULT */ diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c index 8124c554f2cc..9bdb2945afe1 100644 --- a/drivers/iommu/iommufd/pages.c +++ b/drivers/iommu/iommufd/pages.c @@ -1450,7 +1450,7 @@ static void iopt_revoke_notify(struct dma_buf_attachment *attach) pages->dmabuf.phys.len = 0; } -static struct dma_buf_attach_ops iopt_dmabuf_attach_revoke_ops = { +static const struct dma_buf_attach_ops iopt_dmabuf_attach_revoke_ops = { .allow_peer2peer = true, .invalidate_mappings = iopt_revoke_notify, }; diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index 2a82cee7921b..af07c642a526 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -421,19 +421,6 @@ static const struct iommu_dirty_ops amdv1_mock_dirty_ops = { .set_dirty_tracking = mock_domain_set_dirty_tracking, }; -static const struct iommu_domain_ops amdv1_ops = { - IOMMU_PT_DOMAIN_OPS(amdv1), - .free = mock_domain_free, - .attach_dev = mock_domain_nop_attach, - .set_dev_pasid = mock_domain_set_dev_pasid_nop, - .iotlb_sync = &mock_iotlb_sync, -}; - -static const struct iommu_dirty_ops amdv1_dirty_ops = { - IOMMU_PT_DIRTY_OPS(amdv1), - .set_dirty_tracking = mock_domain_set_dirty_tracking, -}; - static struct mock_iommu_domain * mock_domain_alloc_pgtable(struct device *dev, const struct iommu_hwpt_selftest *user_cfg, u32 flags) @@ -477,24 +464,6 @@ mock_domain_alloc_pgtable(struct device *dev, mock->domain.dirty_ops = &amdv1_mock_dirty_ops; break; } - - case MOCK_IOMMUPT_AMDV1: { - struct pt_iommu_amdv1_cfg cfg = {}; - - cfg.common.hw_max_vasz_lg2 = 64; - cfg.common.hw_max_oasz_lg2 = 52; - cfg.common.features = BIT(PT_FEAT_DYNAMIC_TOP) | - BIT(PT_FEAT_AMDV1_ENCRYPT_TABLES) | - BIT(PT_FEAT_AMDV1_FORCE_COHERENCE); - cfg.starting_level = 2; - mock->domain.ops = &amdv1_ops; - rc = pt_iommu_amdv1_init(&mock->amdv1, &cfg, GFP_KERNEL); - if (rc) - goto err_free; - if (flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING) - mock->domain.dirty_ops = &amdv1_dirty_ops; - break; - } default: rc = -EOPNOTSUPP; goto err_free; @@ -636,7 +605,7 @@ static void mock_viommu_destroy(struct iommufd_viommu *viommu) if (mock_viommu->mmap_offset) iommufd_viommu_destroy_mmap(&mock_viommu->core, mock_viommu->mmap_offset); - free_page((unsigned long)mock_viommu->page); + free_pages((unsigned long)mock_viommu->page, 1); mutex_destroy(&mock_viommu->queue_mutex); /* iommufd core frees mock_viommu and viommu */ @@ -870,7 +839,7 @@ static int mock_viommu_init(struct iommufd_viommu *viommu, iommufd_viommu_destroy_mmap(&mock_viommu->core, mock_viommu->mmap_offset); err_free_page: - free_page((unsigned long)mock_viommu->page); + free_pages((unsigned long)mock_viommu->page, 1); return rc; } diff --git a/drivers/iommu/iommufd/vfio_compat.c b/drivers/iommu/iommufd/vfio_compat.c index a258ee2f4579..acb48cdd3b00 100644 --- a/drivers/iommu/iommufd/vfio_compat.c +++ b/drivers/iommu/iommufd/vfio_compat.c @@ -283,7 +283,7 @@ static int iommufd_vfio_check_extension(struct iommufd_ctx *ictx, case VFIO_TYPE1_IOMMU: case VFIO_TYPE1v2_IOMMU: case VFIO_UNMAP_ALL: - return 1; + return !ictx->no_iommu_mode; case VFIO_NOIOMMU_IOMMU: return IS_ENABLED(CONFIG_VFIO_NOIOMMU);