On s390, identity domains are only supported under certain virtualization scenarios. If iommu passthrough is requested but unavailable for a device, ignore the request and instead fall back to dma-iommu with a message. Signed-off-by: Matthew Rosato <mjrosato@xxxxxxxxxxxxx> --- drivers/iommu/s390-iommu.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c index 18979d8109b2..6906e1b5b1b0 100644 --- a/drivers/iommu/s390-iommu.c +++ b/drivers/iommu/s390-iommu.c @@ -462,6 +462,28 @@ static void s390_iommu_get_resv_regions(struct device *dev, } } +static int s390_iommu_def_domain_type(struct device *dev) +{ + struct zpci_dev *zdev = to_zpci_dev(dev); + + /* If strict DMA is requested this takes priority */ + if (iommu_dma_is_strict()) + return IOMMU_DOMAIN_DMA; + + /* DMA_FQ is the default unless passthrough is specified */ + if (!iommu_default_passthrough()) + return IOMMU_DOMAIN_DMA_FQ; + + /* If passthrough specified, CLP must indicate it is allowed. */ + if (zdev->rtr_avail) + return IOMMU_DOMAIN_IDENTITY; + + /* If not allowed, fall back to using translation via DMA_FQ */ + pr_info("Passthrough ignored, translation required for %s.\n", + pci_name(to_pci_dev(dev))); + return IOMMU_DOMAIN_DMA_FQ; +} + static struct iommu_device *s390_iommu_probe_device(struct device *dev) { struct zpci_dev *zdev; @@ -839,6 +861,7 @@ static const struct iommu_ops s390_iommu_ops = { .device_group = generic_device_group, .pgsize_bitmap = SZ_4K, .get_resv_regions = s390_iommu_get_resv_regions, + .def_domain_type = s390_iommu_def_domain_type, .default_domain_ops = &(const struct iommu_domain_ops) { .attach_dev = s390_iommu_attach_device, .map_pages = s390_iommu_map_pages, -- 2.47.0