From: Joerg Roedel Date: Fri, 27 Oct 2023 07:13:40 +0000 (+0200) Subject: Merge branches 'iommu/fixes', 'arm/tegra', 'arm/smmu', 'virtio', 'x86/vt-d', 'x86... X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=e8cca466a84a75f8ff2a7a31173c99ee6d1c59d2;p=linux.git Merge branches 'iommu/fixes', 'arm/tegra', 'arm/smmu', 'virtio', 'x86/vt-d', 'x86/amd', 'core' and 's390' into next --- e8cca466a84a75f8ff2a7a31173c99ee6d1c59d2 diff --cc drivers/iommu/amd/iommu.c index 95bd7c25ba6f3,95bd7c25ba6f3,95bd7c25ba6f3,95bd7c25ba6f3,95bd7c25ba6f3,a284768cb542b,95bd7c25ba6f3,74229b1607a17..089886485895b --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@@@@@@@@ -2092,31 -2092,31 -2092,31 -2092,31 -2092,31 -2129,41 -2092,31 -2092,31 +2129,41 @@@@@@@@@ static struct protection_domain *protec struct io_pgtable_ops *pgtbl_ops; struct protection_domain *domain; int pgtable; ----- -- int mode = DEFAULT_PGTABLE_LEVEL; int ret; +++++ ++ domain = kzalloc(sizeof(*domain), GFP_KERNEL); +++++ ++ if (!domain) +++++ ++ return NULL; +++++ ++ +++++ ++ domain->id = domain_id_alloc(); +++++ ++ if (!domain->id) +++++ ++ goto out_err; +++++ ++ +++++ ++ spin_lock_init(&domain->lock); +++++ ++ INIT_LIST_HEAD(&domain->dev_list); +++++ ++ domain->nid = NUMA_NO_NODE; +++++ ++ +++++ ++ switch (type) { +++++ ++ /* No need to allocate io pgtable ops in passthrough mode */ +++++ ++ case IOMMU_DOMAIN_IDENTITY: +++++ ++ return domain; +++++ ++ case IOMMU_DOMAIN_DMA: +++++ ++ pgtable = amd_iommu_pgtable; +++++ ++ break; /* ----- -- * Force IOMMU v1 page table when iommu=pt and ----- -- * when allocating domain for pass-through devices. +++++ ++ * Force IOMMU v1 page table when allocating +++++ ++ * domain for pass-through devices. */ ----- -- if (type == IOMMU_DOMAIN_IDENTITY) { ----- - pgtable = AMD_IOMMU_V1; ----- - mode = PAGE_MODE_NONE; ----- - } else if (type == IOMMU_DOMAIN_UNMANAGED) { +++++ ++ case IOMMU_DOMAIN_UNMANAGED: pgtable = AMD_IOMMU_V1; - mode = PAGE_MODE_NONE; - } else if (type == IOMMU_DOMAIN_UNMANAGED) { - pgtable = AMD_IOMMU_V1; ----- -- } else if (type == IOMMU_DOMAIN_DMA || type == IOMMU_DOMAIN_DMA_FQ) { ----- -- pgtable = amd_iommu_pgtable; ----- -- } else { ----- -- return NULL; +++++ ++ break; +++++ ++ default: +++++ ++ goto out_err; } ----- -- domain = kzalloc(sizeof(*domain), GFP_KERNEL); ----- -- if (!domain) ----- -- return NULL; ----- -- switch (pgtable) { case AMD_IOMMU_V1: ----- -- ret = protection_domain_init_v1(domain, mode); +++++ ++ ret = protection_domain_init_v1(domain, DEFAULT_PGTABLE_LEVEL); break; case AMD_IOMMU_V2: ret = protection_domain_init_v2(domain); diff --cc drivers/iommu/apple-dart.c index 0b89275084274,2082081402d32,2082081402d32,2082081402d32,2082081402d32,2082081402d32,821b4a3465dfb,22880a42ccaa6..ee05f4824bfad --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@@@@@@@@ -670,28 -670,29 -670,29 -670,29 -670,29 -670,29 -668,56 -671,29 +669,56 @@@@@@@@@ static int apple_dart_attach_dev_paging if (ret) return ret; ------ - switch (domain->type) { - default: ----- - case IOMMU_DOMAIN_DMA: ----- - case IOMMU_DOMAIN_UNMANAGED: ------ - ret = apple_dart_domain_add_streams(dart_domain, cfg); ------ - if (ret) ------ - return ret; ++++++ + for_each_stream_map(i, cfg, stream_map) ++++++ + apple_dart_setup_translation(dart_domain, stream_map); ++++++ + return 0; ++++++ +} ------ - for_each_stream_map(i, cfg, stream_map) ------ - apple_dart_setup_translation(dart_domain, stream_map); ------ - break; ------ - case IOMMU_DOMAIN_BLOCKED: ------ - for_each_stream_map(i, cfg, stream_map) ------ - apple_dart_hw_disable_dma(stream_map); ------ - break; ------ - case IOMMU_DOMAIN_IDENTITY: ------ - for_each_stream_map(i, cfg, stream_map) ------ - apple_dart_hw_enable_bypass(stream_map); ------ - break; ------ - } ++++++ +static int apple_dart_attach_dev_identity(struct iommu_domain *domain, ++++++ + struct device *dev) ++++++ +{ ++++++ + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); ++++++ + struct apple_dart_stream_map *stream_map; ++++++ + int i; ------ - return ret; ++++++ + if (!cfg->stream_maps[0].dart->supports_bypass) ++++++ + return -EINVAL; ++++++ + ++++++ + for_each_stream_map(i, cfg, stream_map) ++++++ + apple_dart_hw_enable_bypass(stream_map); ++++++ + return 0; } ++++++ +static const struct iommu_domain_ops apple_dart_identity_ops = { ++++++ + .attach_dev = apple_dart_attach_dev_identity, ++++++ +}; ++++++ + ++++++ +static struct iommu_domain apple_dart_identity_domain = { ++++++ + .type = IOMMU_DOMAIN_IDENTITY, ++++++ + .ops = &apple_dart_identity_ops, ++++++ +}; ++++++ + ++++++ +static int apple_dart_attach_dev_blocked(struct iommu_domain *domain, ++++++ + struct device *dev) ++++++ +{ ++++++ + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); ++++++ + struct apple_dart_stream_map *stream_map; ++++++ + int i; ++++++ + ++++++ + for_each_stream_map(i, cfg, stream_map) ++++++ + apple_dart_hw_disable_dma(stream_map); ++++++ + return 0; ++++++ +} ++++++ + ++++++ +static const struct iommu_domain_ops apple_dart_blocked_ops = { ++++++ + .attach_dev = apple_dart_attach_dev_blocked, ++++++ +}; ++++++ + ++++++ +static struct iommu_domain apple_dart_blocked_domain = { ++++++ + .type = IOMMU_DOMAIN_BLOCKED, ++++++ + .ops = &apple_dart_blocked_ops, ++++++ +}; ++++++ + static struct iommu_device *apple_dart_probe_device(struct device *dev) { struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); diff --cc drivers/iommu/iommu.c index c146378c7d032,3bfc56df4f781,3bfc56df4f781,3bfc56df4f781,3bfc56df4f781,360f1042e5550,79a0fdb334046,1cc9d139c860c..f17a1113f3d6a --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@@@@@@@@ -1753,11 -1752,11 -1752,11 -1752,11 -1752,11 -1752,11 -1780,22 -1780,22 +1781,22 @@@@@@@@@ iommu_group_alloc_default_domain(struc lockdep_assert_held(&group->mutex); ++++++ /* ++++++ * Allow legacy drivers to specify the domain that will be the default ++++++ * domain. This should always be either an IDENTITY/BLOCKED/PLATFORM ++++++ * domain. Do not use in new drivers. ++++++ */ ++++++ if (ops->default_domain) { ++++++ if (req_type) - return ERR_PTR(-EINVAL); ++++++ + return NULL; ++++++ return ops->default_domain; ++++++ } ++++++ if (req_type) ------ return __iommu_group_alloc_default_domain(bus, group, req_type); ++++++ return __iommu_group_alloc_default_domain(group, req_type); /* The driver gave no guidance on what type to use, try the default */ ------ dom = __iommu_group_alloc_default_domain(bus, group, iommu_def_domain_type); ++++++ dom = __iommu_group_alloc_default_domain(group, iommu_def_domain_type); if (dom) return dom; @@@@@@@@@ -1818,30 -1817,30 -1817,30 -1817,30 -1817,30 -1817,30 -1893,62 -1893,50 +1894,62 @@@@@@@@@ static int iommu_get_default_domain_typ lockdep_assert_held(&group->mutex); ++++++ /* ++++++ * ARM32 drivers supporting CONFIG_ARM_DMA_USE_IOMMU can declare an ++++++ * identity_domain and it will automatically become their default ++++++ * domain. Later on ARM_DMA_USE_IOMMU will install its UNMANAGED domain. ++++++ * Override the selection to IDENTITY. ++++++ */ ++++++ if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { ++++++ static_assert(!(IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) && ++++++ IS_ENABLED(CONFIG_IOMMU_DMA))); ++++++ driver_type = IOMMU_DOMAIN_IDENTITY; ++++++ } ++++++ for_each_group_device(group, gdev) { ------ unsigned int type = iommu_get_def_domain_type(gdev->dev); ------ ------ if (best_type && type && best_type != type) { ------ if (target_type) { ------ dev_err_ratelimited( ------ gdev->dev, ------ "Device cannot be in %s domain\n", ------ iommu_domain_type_str(target_type)); ++++++ driver_type = iommu_get_def_domain_type(group, gdev->dev, ++++++ driver_type); ++++++ ++++++ if (dev_is_pci(gdev->dev) && to_pci_dev(gdev->dev)->untrusted) { ++++++ /* ++++++ * No ARM32 using systems will set untrusted, it cannot ++++++ * work. ++++++ */ ++++++ if (WARN_ON(IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU))) return -1; ------ } ++++++ untrusted = gdev->dev; ++++++ } ++++++ } ------ dev_warn( ------ gdev->dev, ------ "Device needs domain type %s, but device %s in the same iommu group requires type %s - using default\n", ------ iommu_domain_type_str(type), dev_name(last_dev), ------ iommu_domain_type_str(best_type)); ------ return 0; ++++++ + /* ++++++ + * If the common dma ops are not selected in kconfig then we cannot use ++++++ + * IOMMU_DOMAIN_DMA at all. Force IDENTITY if nothing else has been ++++++ + * selected. ++++++ + */ ++++++ + if (!IS_ENABLED(CONFIG_IOMMU_DMA)) { ++++++ + if (WARN_ON(driver_type == IOMMU_DOMAIN_DMA)) ++++++ + return -1; ++++++ + if (!driver_type) ++++++ + driver_type = IOMMU_DOMAIN_IDENTITY; ++++++ + } ++++++ + ++++++ if (untrusted) { ++++++ if (driver_type && driver_type != IOMMU_DOMAIN_DMA) { ++++++ dev_err_ratelimited( ++++++ untrusted, ++++++ "Device is not trusted, but driver is overriding group %u to %s, refusing to probe.\n", ++++++ group->id, iommu_domain_type_str(driver_type)); ++++++ return -1; } ------ if (!best_type) ------ best_type = type; ------ last_dev = gdev->dev; ++++++ driver_type = IOMMU_DOMAIN_DMA; } ------ return best_type; ++++++ ++++++ if (target_type) { ++++++ if (driver_type && target_type != driver_type) ++++++ return -1; ++++++ return target_type; ++++++ } ++++++ return driver_type; } static void iommu_group_do_probe_finalize(struct device *dev) @@@@@@@@@ -1976,10 -1975,10 -1975,10 -1975,10 -1975,10 -1975,10 -2084,17 -2072,15 +2085,17 @@@@@@@@@ static struct iommu_domain *__iommu_dom struct iommu_domain *domain; unsigned int alloc_type = type & IOMMU_DOMAIN_ALLOC_FLAGS; ------ if (bus == NULL || bus->iommu_ops == NULL) ++++++ if (alloc_type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain) ++++++ return ops->identity_domain; ++++++ + else if (alloc_type == IOMMU_DOMAIN_BLOCKED && ops->blocked_domain) ++++++ + return ops->blocked_domain; ++++++ else if (type & __IOMMU_DOMAIN_PAGING && ops->domain_alloc_paging) ++++++ domain = ops->domain_alloc_paging(dev); ++++++ else if (ops->domain_alloc) ++++++ domain = ops->domain_alloc(alloc_type); ++++++ else return NULL; ------ domain = bus->iommu_ops->domain_alloc(alloc_type); if (!domain) return NULL; @@@@@@@@@ -2516,25 -2515,25 -2515,25 -2515,25 -2515,25 -2515,25 -2599,12 -2585,21 +2600,21 @@@@@@@@@ int iommu_map(struct iommu_domain *doma return -EINVAL; ret = __iommu_map(domain, iova, paddr, size, prot, gfp); ------- if (ret == 0 && ops->iotlb_sync_map) ------- ops->iotlb_sync_map(domain, iova, size); +++++++ if (ret == 0 && ops->iotlb_sync_map) { +++++++ ret = ops->iotlb_sync_map(domain, iova, size); +++++++ if (ret) +++++++ goto out_err; +++++++ } + + return ret; ------ } ------ EXPORT_SYMBOL_GPL(iommu_map); + ------ static size_t __iommu_unmap_pages(struct iommu_domain *domain, ------ unsigned long iova, size_t size, ------ struct iommu_iotlb_gather *iotlb_gather) ------ { ------ const struct iommu_domain_ops *ops = domain->ops; ------ size_t pgsize, count; +++++++ out_err: +++++++ /* undo mappings already done */ +++++++ iommu_unmap(domain, iova, size); ------ pgsize = iommu_pgsize(domain, iova, iova, size, &count); ------ return ops->unmap_pages ? ------ ops->unmap_pages(domain, iova, pgsize, count, iotlb_gather) : ------ ops->unmap(domain, iova, pgsize, iotlb_gather); ++++++ return ret; } ++++++ EXPORT_SYMBOL_GPL(iommu_map); static size_t __iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size, diff --cc include/linux/iommu.h index c50a769d569a6,c50a769d569a6,c50a769d569a6,c50a769d569a6,c50a769d569a6,c50a769d569a6,73daa4fb168bc,0c4d8ae985ac6..ddc25d2391063 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@@@@@@@@ -260,6 -260,6 -260,6 -260,6 -260,6 -260,6 -263,13 -263,11 +263,13 @@@@@@@@@ struct iommu_iotlb_gather * will be blocked by the hardware. * @pgsize_bitmap: bitmap of all possible supported page sizes * @owner: Driver module providing these ops ++++++ * @identity_domain: An always available, always attachable identity ++++++ * translation. ++++++ + * @blocked_domain: An always available, always attachable blocking ++++++ + * translation. ++++++ * @default_domain: If not NULL this will always be set as the default domain. ++++++ * This should be an IDENTITY/BLOCKED/PLATFORM domain. ++++++ * Do not use in new drivers. */ struct iommu_ops { bool (*capable)(struct device *dev, enum iommu_cap); @@@@@@@@@ -294,6 -294,6 -294,6 -294,6 -294,6 -294,6 -304,9 -302,8 +304,9 @@@@@@@@@ const struct iommu_domain_ops *default_domain_ops; unsigned long pgsize_bitmap; struct module *owner; ++++++ struct iommu_domain *identity_domain; ++++++ + struct iommu_domain *blocked_domain; ++++++ struct iommu_domain *default_domain; }; /**