Merge branches 'apple/dart', 'arm/exynos', 'arm/renesas', 'arm/smmu', 'x86/vt-d'...
authorJoerg Roedel <jroedel@suse.de>
Sat, 18 Feb 2023 14:43:04 +0000 (15:43 +0100)
committerJoerg Roedel <jroedel@suse.de>
Sat, 18 Feb 2023 14:43:04 +0000 (15:43 +0100)
1  2  3  4  5  6  7  8 
MAINTAINERS
drivers/iommu/amd/iommu.c
drivers/iommu/apple-dart.c
drivers/iommu/exynos-iommu.c
drivers/iommu/intel/iommu.c
drivers/iommu/intel/iommu.h
drivers/iommu/intel/pasid.c
drivers/iommu/iommu.c
drivers/iommu/mtk_iommu_v1.c
drivers/of/address.c
drivers/vfio/vfio_iommu_type1.c

diff --cc MAINTAINERS
Simple merge
Simple merge
index 4f4a323be0d0ffd5279d814c746f4cb3a432d73d,abedcffed23776fb0d9753e3e7f5baa30c020caf,4f4a323be0d0ffd5279d814c746f4cb3a432d73d,4f4a323be0d0ffd5279d814c746f4cb3a432d73d,4f4a323be0d0ffd5279d814c746f4cb3a432d73d,4f4a323be0d0ffd5279d814c746f4cb3a432d73d,4f4a323be0d0ffd5279d814c746f4cb3a432d73d,96843d4688012a38352511893820d1f31294d5a6..06169d36eab829d85b89f01ee1a44edc8b37f80a
@@@@@@@@@ -280,18 -388,63 -280,18 -280,18 -280,18 -280,18 -280,18 -280,18 +388,63 @@@@@@@@@ apple_dart_t8020_hw_stream_command(stru
                if (ret) {
                        dev_err(stream_map->dart->dev,
                                "busy bit did not clear after command %x for streams %lx\n",
- ------                        command, stream_map->sidmap);
+ ++++++                        command, stream_map->sidmap[0]);
+ +++++                 return ret;
+ +++++         }
+ +++++ 
+ +++++         return 0;
+ +++++ }
+ +++++ 
+ +++++ static int
       -apple_dart_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
+ ++++++apple_dart_t8110_hw_tlb_command(struct apple_dart_stream_map *stream_map,
+ ++++++                                u32 command)
+ +++++ {
       -        return apple_dart_hw_stream_command(stream_map,
       -                                            DART_STREAM_COMMAND_INVALIDATE);
+ ++++++        struct apple_dart *dart = stream_map->dart;
+ ++++++        unsigned long flags;
+ ++++++        int ret = 0;
+ ++++++        int sid;
+ ++++++
+ ++++++        spin_lock_irqsave(&dart->lock, flags);
+ ++++++
+ ++++++        for_each_set_bit(sid, stream_map->sidmap, dart->num_streams) {
+ ++++++                u32 val = FIELD_PREP(DART_T8110_TLB_CMD_OP, command) |
+ ++++++                        FIELD_PREP(DART_T8110_TLB_CMD_STREAM, sid);
+ ++++++                writel(val, dart->regs + DART_T8110_TLB_CMD);
+ ++++++
+ ++++++                ret = readl_poll_timeout_atomic(
+ ++++++                        dart->regs + DART_T8110_TLB_CMD, val,
+ ++++++                        !(val & DART_T8110_TLB_CMD_BUSY), 1,
+ ++++++                        DART_STREAM_COMMAND_BUSY_TIMEOUT);
+ ++++++
+ ++++++                if (ret)
+ ++++++                        break;
+ ++++++
+ ++++++        }
+ ++++++
+ ++++++        spin_unlock_irqrestore(&dart->lock, flags);
+ ++++++
+ ++++++        if (ret) {
+ ++++++                dev_err(stream_map->dart->dev,
+ ++++++                        "busy bit did not clear after command %x for stream %d\n",
+ ++++++                        command, sid);
       +                return ret;
       +        }
       +
       +        return 0;
       +}
       +
       +static int
- ----- apple_dart_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
+ ++++++apple_dart_t8020_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
+ ++++++{
+ ++++++        return apple_dart_t8020_hw_stream_command(
+ ++++++                stream_map, DART_T8020_STREAM_COMMAND_INVALIDATE);
+ ++++++}
+ ++++++
+ ++++++static int
+ ++++++apple_dart_t8110_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
       +{
- -----         return apple_dart_hw_stream_command(stream_map,
- -----                                             DART_STREAM_COMMAND_INVALIDATE);
+ ++++++        return apple_dart_t8110_hw_tlb_command(
+ ++++++                stream_map, DART_T8110_TLB_CMD_OP_FLUSH_SID);
        }
        
        static int apple_dart_hw_reset(struct apple_dart *dart)
                apple_dart_hw_clear_all_ttbrs(&stream_map);
        
                /* enable all streams globally since TCR is used to control isolation */
- ------        writel(DART_STREAM_ALL, dart->regs + DART_STREAMS_ENABLE);
+ ++++++        for (i = 0; i < BITS_TO_U32(dart->num_streams); i++)
+ ++++++                writel(U32_MAX, dart->regs + dart->hw->enable_streams + 4 * i);
        
                /* clear any pending errors before the interrupt is unmasked */
- ------        writel(readl(dart->regs + DART_ERROR), dart->regs + DART_ERROR);
+ ++++++        writel(readl(dart->regs + dart->hw->error), dart->regs + dart->hw->error);
+ +++++ 
       -        return apple_dart_hw_invalidate_tlb(&stream_map);
+ ++++++        if (dart->hw->type == DART_T8110)
+ ++++++                writel(0,  dart->regs + DART_T8110_ERROR_MASK);
       +
- -----         return apple_dart_hw_invalidate_tlb(&stream_map);
+ ++++++        return dart->hw->invalidate_tlb(&stream_map);
        }
        
        static void apple_dart_domain_flush_tlb(struct apple_dart_domain *domain)
@@@@@@@@@ -711,17 -899,31 -711,17 -711,17 -711,17 -711,17 -711,17 -688,17 +876,31 @@@@@@@@@ static struct iommu_group *apple_dart_d
                if (!group)
                        goto out;
        
- ------        group_master_cfg = kmemdup(cfg, sizeof(*group_master_cfg), GFP_KERNEL);
- ------        if (!group_master_cfg) {
- ------                iommu_group_put(group);
- ------                goto out;
- ------        }
+ ++++++        group_master_cfg = iommu_group_get_iommudata(group);
+ ++++++        if (group_master_cfg) {
+ ++++++                int ret;
+ +++++ 
       -        iommu_group_set_iommudata(group, group_master_cfg,
       -                apple_dart_release_group);
+ ++++++                ret = apple_dart_merge_master_cfg(group_master_cfg, cfg);
+ ++++++                if (ret) {
+ ++++++                        dev_err(dev, "Failed to merge DART IOMMU grups.\n");
+ ++++++                        iommu_group_put(group);
+ ++++++                        res = ERR_PTR(ret);
+ ++++++                        goto out;
+ ++++++                }
+ ++++++        } else {
+ ++++++                group_master_cfg = kmemdup(cfg, sizeof(*group_master_cfg),
+ ++++++                                           GFP_KERNEL);
+ ++++++                if (!group_master_cfg) {
+ ++++++                        iommu_group_put(group);
+ ++++++                        goto out;
+ ++++++                }
       +
- -----         iommu_group_set_iommudata(group, group_master_cfg,
- -----                 apple_dart_release_group);
+ ++++++                iommu_group_set_iommudata(group, group_master_cfg,
+ ++++++                        apple_dart_release_group);
+ ++++++        }
        
                for_each_stream_map(i, cfg, stream_map)
- ------                for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
+ ++++++                for_each_set_bit(sid, stream_map->sidmap, stream_map->dart->num_streams)
                                stream_map->dart->sid2group[sid] = group;
        
                res = group;
index b0cde22119875eadcfb36cbc637d2a48133a70b6,b0cde22119875eadcfb36cbc637d2a48133a70b6,69fd7fa3e49a4606d9a188903ce98c251e039cf8,b0cde22119875eadcfb36cbc637d2a48133a70b6,b0cde22119875eadcfb36cbc637d2a48133a70b6,b0cde22119875eadcfb36cbc637d2a48133a70b6,b0cde22119875eadcfb36cbc637d2a48133a70b6,7eaa58ced4aea991811c93f5a4a91c089561c34a..483aaaeb6daeac685dbead517c6409f54b2db807
@@@@@@@@@ -312,9 -312,9 -380,27 -312,9 -312,9 -312,9 -312,9 -312,9 +380,27 @@@@@@@@@ static const struct sysmmu_variant sysm
                .flush_end      = 0x24,
                .int_status     = 0x60,
                .int_clear      = 0x64,
-- ---- /* SysMMU v7: VM capable register set */
++ +++++
++ +++++        .get_fault_info = exynos_sysmmu_v5_get_fault_info,
       +};
       +
       -/* SysMMU v7: VM capable register set */
++ +++++/* SysMMU v7: non-VM capable register layout */
++ +++++static const struct sysmmu_variant sysmmu_v7_variant = {
++ +++++        .pt_base        = 0x0c,
++ +++++        .flush_all      = 0x10,
++ +++++        .flush_entry    = 0x14,
++ +++++        .flush_range    = 0x18,
++ +++++        .flush_start    = 0x20,
++ +++++        .flush_end      = 0x24,
++ +++++        .int_status     = 0x60,
++ +++++        .int_clear      = 0x64,
++ +++++        .fault_va       = 0x70,
++ +++++        .fault_info     = 0x78,
++ +++++
++ +++++        .get_fault_info = exynos_sysmmu_v7_get_fault_info,
++ ++++ };
++ ++++ 
++ +++++/* SysMMU v7: VM capable register layout */
        static const struct sysmmu_variant sysmmu_v7_vm_variant = {
                .pt_base        = 0x800c,
                .flush_all      = 0x8010,
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 2209372f236dbb84d1b77c335c3acbe3d9584e82,23c24fe98c00d4a07ef73826a02d81386cf2118d,23c24fe98c00d4a07ef73826a02d81386cf2118d,23c24fe98c00d4a07ef73826a02d81386cf2118d,23c24fe98c00d4a07ef73826a02d81386cf2118d,23c24fe98c00d4a07ef73826a02d81386cf2118d,23c24fe98c00d4a07ef73826a02d81386cf2118d,e14f86a8ef52586a30a4f3829289f42a06205bc4..5600eb67ca30105e8de6f0527a1b6080b5ecab38
@@@@@@@@@ -1867,22 -1865,15 -1865,15 -1865,15 -1865,15 -1865,15 -1865,15 -1866,15 +1868,22 @@@@@@@@@ static void vfio_test_domain_fgsp(struc
                if (!pages)
                        return;
        
 -------        ret = iommu_map(domain->domain, 0, page_to_phys(pages), PAGE_SIZE * 2,
 ------                         IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
       -                        IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE, GFP_KERNEL);
 -------        if (!ret) {
 -------                size_t unmapped = iommu_unmap(domain->domain, 0, PAGE_SIZE);
 +++++++        list_for_each_entry(region, regions, list) {
 +++++++                start = ALIGN(region->start, PAGE_SIZE * 2);
 +++++++                if (start >= region->end || (region->end - start < PAGE_SIZE * 2))
 +++++++                        continue;
        
 -------                if (unmapped == PAGE_SIZE)
 -------                        iommu_unmap(domain->domain, PAGE_SIZE, PAGE_SIZE);
 -------                else
 -------                        domain->fgsp = true;
 +++++++                ret = iommu_map(domain->domain, start, page_to_phys(pages), PAGE_SIZE * 2,
-                                       IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
++++++++                                IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE, GFP_KERNEL);
 +++++++                if (!ret) {
 +++++++                        size_t unmapped = iommu_unmap(domain->domain, start, PAGE_SIZE);
 +++++++
 +++++++                        if (unmapped == PAGE_SIZE)
 +++++++                                iommu_unmap(domain->domain, start + PAGE_SIZE, PAGE_SIZE);
 +++++++                        else
 +++++++                                domain->fgsp = true;
 +++++++                }
 +++++++                break;
                }
        
                __free_pages(pages, order);