]> Git Repo - J-linux.git/commitdiff
Merge branches 'apple/dart', 'arm/rockchip', 'arm/smmu', 'virtio', 'x86/vt-d', 'x86...
authorJoerg Roedel <[email protected]>
Wed, 3 Jan 2024 08:59:32 +0000 (09:59 +0100)
committerJoerg Roedel <[email protected]>
Wed, 3 Jan 2024 08:59:32 +0000 (09:59 +0100)
14 files changed:
1  2  3  4  5  6  7  8 
arch/x86/Kconfig
drivers/iommu/amd/iommu.c
drivers/iommu/apple-dart.c
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
drivers/iommu/arm/arm-smmu/arm-smmu.c
drivers/iommu/arm/arm-smmu/qcom_iommu.c
drivers/iommu/intel/iommu.c
drivers/iommu/intel/iommu.h
drivers/iommu/intel/svm.c
drivers/iommu/iommufd/hw_pagetable.c
drivers/iommu/of_iommu.c
drivers/iommu/virtio-iommu.c
include/linux/device.h
mm/Kconfig

diff --combined arch/x86/Kconfig
index 1566748f16c424f89c8b384e50d127c0093df26f,3762f41bb092971e3f6180f057b49742014e5f11,3762f41bb092971e3f6180f057b49742014e5f11,3762f41bb092971e3f6180f057b49742014e5f11,3762f41bb092971e3f6180f057b49742014e5f11,3762f41bb092971e3f6180f057b49742014e5f11,3762f41bb092971e3f6180f057b49742014e5f11,68a2ec36a46ec6b91fa072bc83e75e48c044a89c..ffad5aa89343157f52f48f0c50e30e42b92f433a
@@@@@@@@@ -71,6 -71,6 -71,6 -71,6 -71,6 -71,6 -71,6 -71,7 +71,7 @@@@@@@@@ config X8
                select ARCH_HAS_CACHE_LINE_SIZE
                select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
                select ARCH_HAS_CPU_FINALIZE_INIT
+++++++         select ARCH_HAS_CPU_PASID               if IOMMU_SVA
                select ARCH_HAS_CURRENT_STACK_POINTER
                select ARCH_HAS_DEBUG_VIRTUAL
                select ARCH_HAS_DEBUG_VM_PGTABLE        if !X86_PAE
@@@@@@@@@ -2072,7 -2072,7 -2072,7 -2072,7 -2072,7 -2072,7 -2072,7 -2073,7 +2073,7 @@@@@@@@@ config ARCH_SUPPORTS_KEXE
                def_bool y
        
        config ARCH_SUPPORTS_KEXEC_FILE
 -------        def_bool X86_64 && CRYPTO && CRYPTO_SHA256
 +++++++        def_bool X86_64
        
        config ARCH_SELECTS_KEXEC_FILE
                def_bool y
                select HAVE_IMA_KEXEC if IMA
        
        config ARCH_SUPPORTS_KEXEC_PURGATORY
 -------        def_bool KEXEC_FILE
 +++++++        def_bool y
        
        config ARCH_SUPPORTS_KEXEC_SIG
                def_bool y
index fcc987f5d4edc3ae87335fceed57eb26d7ba9b00,fcc987f5d4edc3ae87335fceed57eb26d7ba9b00,fcc987f5d4edc3ae87335fceed57eb26d7ba9b00,fcc987f5d4edc3ae87335fceed57eb26d7ba9b00,fcc987f5d4edc3ae87335fceed57eb26d7ba9b00,fcc987f5d4edc3ae87335fceed57eb26d7ba9b00,255ea754c0cdd5adda882c5b866f0c3468610021,8199c678c2dc2a3ce32cddb85f117620852f40ca..92d6596bdfffb349655201021957d34891daf828
@@@@@@@@@ -64,7 -64,7 -64,7 -64,7 -64,7 -64,7 -64,7 -64,7 +64,7 @@@@@@@@@ LIST_HEAD(hpet_map)
        LIST_HEAD(acpihid_map);
        
        const struct iommu_ops amd_iommu_ops;
------ -const struct iommu_dirty_ops amd_dirty_ops;
++++++ +static const struct iommu_dirty_ops amd_dirty_ops;
        
        int amd_iommu_max_glx_val = -1;
        
@@@@@@@@@ -85,6 -85,6 -85,6 -85,6 -85,6 -85,6 -85,11 -85,6 +85,11 @@@@@@@@@ static void detach_device(struct devic
         *
         ****************************************************************************/
        
++++++ +static inline bool pdom_is_v2_pgtbl_mode(struct protection_domain *pdom)
++++++ +{
++++++ +        return (pdom && (pdom->flags & PD_IOMMUV2_MASK));
++++++ +}
++++++ +
        static inline int get_acpihid_device_id(struct device *dev,
                                                struct acpihid_map_entry **entry)
        {
@@@@@@@@@ -551,8 -551,8 -551,8 -551,8 -551,8 -551,8 -556,8 -551,6 +556,6 @@@@@@@@@ static void amd_iommu_uninit_device(str
                if (dev_data->domain)
                        detach_device(dev);
        
-------         dev_iommu_priv_set(dev, NULL);
------- 
                /*
                 * We keep dev_data around for unplugged devices and reuse it when the
                 * device is re-plugged - not doing so would introduce a ton of races.
@@@@@@@@@ -1124,68 -1124,68 -1124,68 -1124,68 -1124,68 -1124,68 -1129,44 -1122,68 +1127,44 @@@@@@@@@ static inline u64 build_inv_address(u6
        }
        
        static void build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,
------ -                                  size_t size, u16 domid, int pde)
++++++ +                                  size_t size, u16 domid,
++++++ +                                  ioasid_t pasid, bool gn)
        {
                u64 inv_address = build_inv_address(address, size);
        
                memset(cmd, 0, sizeof(*cmd));
++++++ +
                cmd->data[1] |= domid;
                cmd->data[2]  = lower_32_bits(inv_address);
                cmd->data[3]  = upper_32_bits(inv_address);
++++++ +        /* PDE bit - we want to flush everything, not only the PTEs */
++++++ +        cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
++++++ +        if (gn) {
++++++ +                cmd->data[0] |= pasid;
++++++ +                cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;
++++++ +        }
                CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);
------ -        if (pde) /* PDE bit - we want to flush everything, not only the PTEs */
------ -                cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
        }
        
        static void build_inv_iotlb_pages(struct iommu_cmd *cmd, u16 devid, int qdep,
------ -                                  u64 address, size_t size)
++++++ +                                  u64 address, size_t size,
++++++ +                                  ioasid_t pasid, bool gn)
        {
                u64 inv_address = build_inv_address(address, size);
        
                memset(cmd, 0, sizeof(*cmd));
++++++ +
                cmd->data[0]  = devid;
                cmd->data[0] |= (qdep & 0xff) << 24;
                cmd->data[1]  = devid;
                cmd->data[2]  = lower_32_bits(inv_address);
                cmd->data[3]  = upper_32_bits(inv_address);
------ -        CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES);
------ -}
------ -
------ -static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, u32 pasid,
------ -                                  u64 address, bool size)
------ -{
------ -        memset(cmd, 0, sizeof(*cmd));
------ -
------ -        address &= ~(0xfffULL);
------ -
------ -        cmd->data[0]  = pasid;
------ -        cmd->data[1]  = domid;
------ -        cmd->data[2]  = lower_32_bits(address);
------ -        cmd->data[3]  = upper_32_bits(address);
------ -        cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
------ -        cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;
------ -        if (size)
------ -                cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
------ -        CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);
------ -}
------ -
------ -static void build_inv_iotlb_pasid(struct iommu_cmd *cmd, u16 devid, u32 pasid,
------ -                                  int qdep, u64 address, bool size)
------ -{
------ -        memset(cmd, 0, sizeof(*cmd));
------ -
------ -        address &= ~(0xfffULL);
++++++ +        if (gn) {
++++++ +                cmd->data[0] |= ((pasid >> 8) & 0xff) << 16;
++++++ +                cmd->data[1] |= (pasid & 0xff) << 16;
++++++ +                cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;
++++++ +        }
        
------ -        cmd->data[0]  = devid;
------ -        cmd->data[0] |= ((pasid >> 8) & 0xff) << 16;
------ -        cmd->data[0] |= (qdep  & 0xff) << 24;
------ -        cmd->data[1]  = devid;
------ -        cmd->data[1] |= (pasid & 0xff) << 16;
------ -        cmd->data[2]  = lower_32_bits(address);
------ -        cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;
------ -        cmd->data[3]  = upper_32_bits(address);
------ -        if (size)
------ -                cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
                CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES);
        }
        
@@@@@@@@@ -1341,7 -1341,7 -1341,7 -1341,7 -1341,7 -1341,7 -1322,7 -1339,7 +1320,7 @@@@@@@@@ static void amd_iommu_flush_tlb_all(str
                for (dom_id = 0; dom_id <= last_bdf; ++dom_id) {
                        struct iommu_cmd cmd;
                        build_inv_iommu_pages(&cmd, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
------ -                                      dom_id, 1);
++++++ +                                      dom_id, IOMMU_NO_PASID, false);
                        iommu_queue_command(iommu, &cmd);
                }
        
@@@@@@@@@ -1353,7 -1353,7 -1353,7 -1353,7 -1353,7 -1353,7 -1334,7 -1351,7 +1332,7 @@@@@@@@@ static void amd_iommu_flush_tlb_domid(s
                struct iommu_cmd cmd;
        
                build_inv_iommu_pages(&cmd, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
------ -                              dom_id, 1);
++++++ +                              dom_id, IOMMU_NO_PASID, false);
                iommu_queue_command(iommu, &cmd);
        
                iommu_completion_wait(iommu);
@@@@@@@@@ -1392,7 -1392,7 -1392,7 -1392,7 -1392,7 -1392,7 -1373,7 -1390,7 +1371,7 @@@@@@@@@ static void amd_iommu_flush_irt_all(str
                iommu_completion_wait(iommu);
        }
        
------ -void iommu_flush_all_caches(struct amd_iommu *iommu)
++++++ +void amd_iommu_flush_all_caches(struct amd_iommu *iommu)
        {
                if (check_feature(FEATURE_IA)) {
                        amd_iommu_flush_all(iommu);
        /*
         * Command send function for flushing on-device TLB
         */
------ -static int device_flush_iotlb(struct iommu_dev_data *dev_data,
------ -                              u64 address, size_t size)
++++++ +static int device_flush_iotlb(struct iommu_dev_data *dev_data, u64 address,
++++++ +                              size_t size, ioasid_t pasid, bool gn)
        {
                struct amd_iommu *iommu;
                struct iommu_cmd cmd;
                if (!iommu)
                        return -EINVAL;
        
------ -        build_inv_iotlb_pages(&cmd, dev_data->devid, qdep, address, size);
++++++ +        build_inv_iotlb_pages(&cmd, dev_data->devid, qdep, address,
++++++ +                              size, pasid, gn);
        
                return iommu_queue_command(iommu, &cmd);
        }
@@@@@@@@@ -1464,8 -1464,8 -1464,8 -1464,8 -1464,8 -1464,8 -1446,11 -1462,8 +1444,11 @@@@@@@@@ static int device_flush_dte(struct iomm
                                return ret;
                }
        
------ -        if (dev_data->ats_enabled)
------ -                ret = device_flush_iotlb(dev_data, 0, ~0UL);
++++++ +        if (dev_data->ats_enabled) {
++++++ +                /* Invalidate the entire contents of an IOTLB */
++++++ +                ret = device_flush_iotlb(dev_data, 0, ~0UL,
++++++ +                                         IOMMU_NO_PASID, false);
++++++ +        }
        
                return ret;
        }
         * page. Otherwise it flushes the whole TLB of the IOMMU.
         */
        static void __domain_flush_pages(struct protection_domain *domain,
------ -                                 u64 address, size_t size, int pde)
++++++ +                                 u64 address, size_t size)
        {
                struct iommu_dev_data *dev_data;
                struct iommu_cmd cmd;
                int ret = 0, i;
++++++ +        ioasid_t pasid = IOMMU_NO_PASID;
++++++ +        bool gn = false;
++++++ +
++++++ +        if (pdom_is_v2_pgtbl_mode(domain))
++++++ +                gn = true;
        
------ -        build_inv_iommu_pages(&cmd, address, size, domain->id, pde);
++++++ +        build_inv_iommu_pages(&cmd, address, size, domain->id, pasid, gn);
        
                for (i = 0; i < amd_iommu_get_num_iommus(); ++i) {
                        if (!domain->dev_iommu[i])
                        if (!dev_data->ats_enabled)
                                continue;
        
------ -                ret |= device_flush_iotlb(dev_data, address, size);
++++++ +                ret |= device_flush_iotlb(dev_data, address, size, pasid, gn);
                }
        
                WARN_ON(ret);
        }
        
------ -static void domain_flush_pages(struct protection_domain *domain,
------ -                               u64 address, size_t size, int pde)
++++++ +void amd_iommu_domain_flush_pages(struct protection_domain *domain,
++++++ +                                  u64 address, size_t size)
        {
                if (likely(!amd_iommu_np_cache)) {
------ -                __domain_flush_pages(domain, address, size, pde);
++++++ +                __domain_flush_pages(domain, address, size);
++++++ +
++++++ +                /* Wait until IOMMU TLB and all device IOTLB flushes are complete */
++++++ +                amd_iommu_domain_flush_complete(domain);
++++++ +
                        return;
                }
        
        
                        flush_size = 1ul << min_alignment;
        
------ -                __domain_flush_pages(domain, address, flush_size, pde);
++++++ +                __domain_flush_pages(domain, address, flush_size);
                        address += flush_size;
                        size -= flush_size;
                }
++++++ +
++++++ +        /* Wait until IOMMU TLB and all device IOTLB flushes are complete */
++++++ +        amd_iommu_domain_flush_complete(domain);
        }
        
        /* Flush the whole IO/TLB for a given protection domain - including PDE */
------ -void amd_iommu_domain_flush_tlb_pde(struct protection_domain *domain)
++++++ +static void amd_iommu_domain_flush_all(struct protection_domain *domain)
        {
------ -        domain_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1);
++++++ +        amd_iommu_domain_flush_pages(domain, 0,
++++++ +                                     CMD_INV_IOMMU_ALL_PAGES_ADDRESS);
        }
        
        void amd_iommu_domain_flush_complete(struct protection_domain *domain)
@@@@@@@@@ -1579,8 -1579,8 -1579,8 -1579,8 -1579,8 -1579,8 -1577,7 -1577,8 +1575,7 @@@@@@@@@ static void domain_flush_np_cache(struc
                        unsigned long flags;
        
                        spin_lock_irqsave(&domain->lock, flags);
------ -                domain_flush_pages(domain, iova, size, 1);
------ -                amd_iommu_domain_flush_complete(domain);
++++++ +                amd_iommu_domain_flush_pages(domain, iova, size);
                        spin_unlock_irqrestore(&domain->lock, flags);
                }
        }
@@@@@@@@@ -1858,11 -1858,11 -1858,11 -1858,11 -1858,11 -1858,11 -1855,8 -1856,11 +1853,8 @@@@@@@@@ static void do_detach(struct iommu_dev_
                /* Flush the DTE entry */
                device_flush_dte(dev_data);
        
------ -        /* Flush IOTLB */
------ -        amd_iommu_domain_flush_tlb_pde(domain);
------ -
------ -        /* Wait for the flushes to finish */
------ -        amd_iommu_domain_flush_complete(domain);
++++++ +        /* Flush IOTLB and wait for the flushes to finish */
++++++ +        amd_iommu_domain_flush_all(domain);
        
                /* decrease reference counters - needs to happen after the flushes */
                domain->dev_iommu[iommu->index] -= 1;
@@@@@@@@@ -1896,15 -1896,15 -1896,15 -1896,15 -1896,15 -1896,15 -1890,6 -1894,15 +1888,6 @@@@@@@@@ static int attach_device(struct device 
        
                do_attach(dev_data, domain);
        
------ -        /*
------ -         * We might boot into a crash-kernel here. The crashed kernel
------ -         * left the caches in the IOMMU dirty. So we have to flush
------ -         * here to evict all dirty stuff.
------ -         */
------ -        amd_iommu_domain_flush_tlb_pde(domain);
------ -
------ -        amd_iommu_domain_flush_complete(domain);
------ -
        out:
                spin_unlock(&dev_data->lock);
        
@@@@@@@@@ -2048,8 -2048,8 -2048,8 -2048,8 -2048,8 -2048,8 -2033,7 -2046,8 +2031,7 @@@@@@@@@ void amd_iommu_domain_update(struct pro
                amd_iommu_update_and_flush_device_table(domain);
        
                /* Flush domain TLB(s) and wait for completion */
------ -        amd_iommu_domain_flush_tlb_pde(domain);
------ -        amd_iommu_domain_flush_complete(domain);
++++++ +        amd_iommu_domain_flush_all(domain);
        }
        
        /*****************************************************************************
@@@@@@@@@ -2482,10 -2482,10 -2482,10 -2482,10 -2482,10 -2482,10 -2466,9 -2480,10 +2464,9 @@@@@@@@@ static int amd_iommu_set_dirty_tracking
                }
        
                /* Flush IOTLB to mark IOPTE dirty on the next translation(s) */
------ -        if (domain_flush) {
------ -                amd_iommu_domain_flush_tlb_pde(pdomain);
------ -                amd_iommu_domain_flush_complete(pdomain);
------ -        }
++++++ +        if (domain_flush)
++++++ +                amd_iommu_domain_flush_all(pdomain);
++++++ +
                pdomain->dirty_tracking = enable;
                spin_unlock_irqrestore(&pdomain->lock, flags);
        
@@@@@@@@@ -2588,8 -2588,8 -2588,8 -2588,8 -2588,8 -2588,8 -2571,7 -2586,8 +2569,7 @@@@@@@@@ static void amd_iommu_flush_iotlb_all(s
                unsigned long flags;
        
                spin_lock_irqsave(&dom->lock, flags);
------ -        amd_iommu_domain_flush_tlb_pde(dom);
------ -        amd_iommu_domain_flush_complete(dom);
++++++ +        amd_iommu_domain_flush_all(dom);
                spin_unlock_irqrestore(&dom->lock, flags);
        }
        
@@@@@@@@@ -2600,8 -2600,8 -2600,8 -2600,8 -2600,8 -2600,8 -2582,8 -2598,8 +2580,8 @@@@@@@@@ static void amd_iommu_iotlb_sync(struc
                unsigned long flags;
        
                spin_lock_irqsave(&dom->lock, flags);
------ -        domain_flush_pages(dom, gather->start, gather->end - gather->start + 1, 1);
------ -        amd_iommu_domain_flush_complete(dom);
++++++ +        amd_iommu_domain_flush_pages(dom, gather->start,
++++++ +                                     gather->end - gather->start + 1);
                spin_unlock_irqrestore(&dom->lock, flags);
        }
        
@@@@@@@@@ -2635,7 -2635,7 -2635,7 -2635,7 -2635,7 -2635,7 -2617,7 -2633,7 +2615,7 @@@@@@@@@ static bool amd_iommu_enforce_cache_coh
                return true;
        }
        
------ -const struct iommu_dirty_ops amd_dirty_ops = {
++++++ +static const struct iommu_dirty_ops amd_dirty_ops = {
                .set_dirty_tracking = amd_iommu_set_dirty_tracking,
                .read_and_clear_dirty = amd_iommu_read_and_clear_dirty,
        };
@@@@@@@@@ -2666,7 -2666,7 -2666,7 -2666,7 -2666,7 -2666,7 -2648,7 -2664,7 +2646,7 @@@@@@@@@ const struct iommu_ops amd_iommu_ops = 
        };
        
        static int __flush_pasid(struct protection_domain *domain, u32 pasid,
------ -                         u64 address, bool size)
++++++ +                         u64 address, size_t size)
        {
                struct iommu_dev_data *dev_data;
                struct iommu_cmd cmd;
                if (!(domain->flags & PD_IOMMUV2_MASK))
                        return -EINVAL;
        
------ -        build_inv_iommu_pasid(&cmd, domain->id, pasid, address, size);
++++++ +        build_inv_iommu_pages(&cmd, address, size, domain->id, pasid, true);
        
                /*
                 * IOMMU TLB needs to be flushed before Device TLB to
                        iommu = rlookup_amd_iommu(dev_data->dev);
                        if (!iommu)
                                continue;
------ -                build_inv_iotlb_pasid(&cmd, dev_data->devid, pasid,
------ -                                      qdep, address, size);
++++++ +                build_inv_iotlb_pages(&cmd, dev_data->devid, qdep,
++++++ +                                      address, size, pasid, true);
        
                        ret = iommu_queue_command(iommu, &cmd);
                        if (ret != 0)
        static int __amd_iommu_flush_page(struct protection_domain *domain, u32 pasid,
                                          u64 address)
        {
------ -        return __flush_pasid(domain, pasid, address, false);
++++++ +        return __flush_pasid(domain, pasid, address, PAGE_SIZE);
        }
        
        int amd_iommu_flush_page(struct iommu_domain *dom, u32 pasid,
        
        static int __amd_iommu_flush_tlb(struct protection_domain *domain, u32 pasid)
        {
------ -        return __flush_pasid(domain, pasid, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
------ -                             true);
++++++ +        return __flush_pasid(domain, pasid, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS);
        }
        
        int amd_iommu_flush_tlb(struct iommu_domain *dom, u32 pasid)
                return index;
        }
        
------ -static int modify_irte_ga(struct amd_iommu *iommu, u16 devid, int index,
------ -                          struct irte_ga *irte)
++++++ +static int __modify_irte_ga(struct amd_iommu *iommu, u16 devid, int index,
++++++ +                            struct irte_ga *irte)
        {
                struct irq_remap_table *table;
                struct irte_ga *entry;
        
                raw_spin_unlock_irqrestore(&table->lock, flags);
        
++++++ +        return 0;
++++++ +}
++++++ +
++++++ +static int modify_irte_ga(struct amd_iommu *iommu, u16 devid, int index,
++++++ +                          struct irte_ga *irte)
++++++ +{
++++++ +        bool ret;
++++++ +
++++++ +        ret = __modify_irte_ga(iommu, devid, index, irte);
++++++ +        if (ret)
++++++ +                return ret;
++++++ +
                iommu_flush_irt_and_complete(iommu, devid);
        
                return 0;
@@@@@@@@@ -3822,8 -3822,8 -3822,8 -3822,8 -3822,8 -3822,8 -3815,8 -3820,8 +3813,8 @@@@@@@@@ int amd_iommu_update_ga(int cpu, bool i
                }
                entry->lo.fields_vapic.is_run = is_run;
        
------ -        return modify_irte_ga(ir_data->iommu, ir_data->irq_2_irte.devid,
------ -                              ir_data->irq_2_irte.index, entry);
++++++ +        return __modify_irte_ga(ir_data->iommu, ir_data->irq_2_irte.devid,
++++++ +                                ir_data->irq_2_irte.index, entry);
        }
        EXPORT_SYMBOL(amd_iommu_update_ga);
        #endif
index ee05f4824bfad1d6515fd506e9c1c2fd6760e18f,497a516747bd78da4973674b30f6275c381bdefe,ee05f4824bfad1d6515fd506e9c1c2fd6760e18f,ee05f4824bfad1d6515fd506e9c1c2fd6760e18f,ee05f4824bfad1d6515fd506e9c1c2fd6760e18f,ee05f4824bfad1d6515fd506e9c1c2fd6760e18f,ee05f4824bfad1d6515fd506e9c1c2fd6760e18f,56cfc33042e0b5f55df3d4ed7387d6ea6a72094f..ef3ee95706dac0997d18f9de6598f529df66064c
        #define DART_T8020_TCR_BYPASS_DAPF      BIT(12)
        
        #define DART_T8020_TTBR       0x200
+ ++++++#define DART_T8020_USB4_TTBR  0x400
        #define DART_T8020_TTBR_VALID BIT(31)
        #define DART_T8020_TTBR_ADDR_FIELD_SHIFT 0
        #define DART_T8020_TTBR_SHIFT 12
@@@@@@@@@ -368,12 -369,14 -368,12 -368,12 -368,12 -368,12 -368,12 -368,12 +369,14 @@@@@@@@@ apple_dart_t8020_hw_stream_command(stru
                                     u32 command)
        {
                unsigned long flags;
- ------        int ret;
+ ++++++        int ret, i;
                u32 command_reg;
        
                spin_lock_irqsave(&stream_map->dart->lock, flags);
        
- ------        writel(stream_map->sidmap[0], stream_map->dart->regs + DART_T8020_STREAM_SELECT);
+ ++++++        for (i = 0; i < BITS_TO_U32(stream_map->dart->num_streams); i++)
+ ++++++                writel(stream_map->sidmap[i],
+ ++++++                       stream_map->dart->regs + DART_T8020_STREAM_SELECT + 4 * i);
                writel(command, stream_map->dart->regs + DART_T8020_STREAM_COMMAND);
        
                ret = readl_poll_timeout_atomic(
@@@@@@@@@ -740,7 -743,7 -740,7 -740,7 -740,7 -740,7 -740,7 -740,6 +743,6 @@@@@@@@@ static void apple_dart_release_device(s
        {
                struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
        
-------         dev_iommu_priv_set(dev, NULL);
                kfree(cfg);
        }
        
@@@@@@@@@ -908,7 -911,7 -908,7 -908,7 -908,7 -908,7 -908,7 -907,7 +910,7 @@@@@@@@@ static struct iommu_group *apple_dart_d
        
                        ret = apple_dart_merge_master_cfg(group_master_cfg, cfg);
                        if (ret) {
- ------                        dev_err(dev, "Failed to merge DART IOMMU grups.\n");
+ ++++++                        dev_err(dev, "Failed to merge DART IOMMU groups.\n");
                                iommu_group_put(group);
                                res = ERR_PTR(ret);
                                goto out;
@@@@@@@@@ -1215,6 -1218,33 -1215,6 -1215,6 -1215,6 -1215,6 -1215,6 -1214,6 +1217,33 @@@@@@@@@ static const struct apple_dart_hw apple
                .ttbr_shift = DART_T8020_TTBR_SHIFT,
                .ttbr_count = 4,
        };
+ ++++++
+ ++++++static const struct apple_dart_hw apple_dart_hw_t8103_usb4 = {
+ ++++++        .type = DART_T8020,
+ ++++++        .irq_handler = apple_dart_t8020_irq,
+ ++++++        .invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb,
+ ++++++        .oas = 36,
+ ++++++        .fmt = APPLE_DART,
+ ++++++        .max_sid_count = 64,
+ ++++++
+ ++++++        .enable_streams = DART_T8020_STREAMS_ENABLE,
+ ++++++        .lock = DART_T8020_CONFIG,
+ ++++++        .lock_bit = DART_T8020_CONFIG_LOCK,
+ ++++++
+ ++++++        .error = DART_T8020_ERROR,
+ ++++++
+ ++++++        .tcr = DART_T8020_TCR,
+ ++++++        .tcr_enabled = DART_T8020_TCR_TRANSLATE_ENABLE,
+ ++++++        .tcr_disabled = 0,
+ ++++++        .tcr_bypass = 0,
+ ++++++
+ ++++++        .ttbr = DART_T8020_USB4_TTBR,
+ ++++++        .ttbr_valid = DART_T8020_TTBR_VALID,
+ ++++++        .ttbr_addr_field_shift = DART_T8020_TTBR_ADDR_FIELD_SHIFT,
+ ++++++        .ttbr_shift = DART_T8020_TTBR_SHIFT,
+ ++++++        .ttbr_count = 4,
+ ++++++};
+ ++++++
        static const struct apple_dart_hw apple_dart_hw_t6000 = {
                .type = DART_T6000,
                .irq_handler = apple_dart_t8020_irq,
@@@@@@@@@ -1272,7 -1302,7 -1272,7 -1272,7 -1272,7 -1272,7 -1272,7 -1271,7 +1301,7 @@@@@@@@@ static __maybe_unused int apple_dart_su
                unsigned int sid, idx;
        
                for (sid = 0; sid < dart->num_streams; sid++) {
- ------                dart->save_tcr[sid] = readl_relaxed(dart->regs + DART_TCR(dart, sid));
+ ++++++                dart->save_tcr[sid] = readl(dart->regs + DART_TCR(dart, sid));
                        for (idx = 0; idx < dart->hw->ttbr_count; idx++)
                                dart->save_ttbr[sid][idx] =
                                        readl(dart->regs + DART_TTBR(dart, sid, idx));
@@@@@@@@@ -1307,6 -1337,7 -1307,6 -1307,6 -1307,6 -1307,6 -1307,6 -1306,6 +1336,7 @@@@@@@@@ static DEFINE_SIMPLE_DEV_PM_OPS(apple_d
        
        static const struct of_device_id apple_dart_of_match[] = {
                { .compatible = "apple,t8103-dart", .data = &apple_dart_hw_t8103 },
+ ++++++        { .compatible = "apple,t8103-usb4-dart", .data = &apple_dart_hw_t8103_usb4 },
                { .compatible = "apple,t8110-dart", .data = &apple_dart_hw_t8110 },
                { .compatible = "apple,t6000-dart", .data = &apple_dart_hw_t6000 },
                {},
index 7445454c2af244f03b9274db12e3e4dd325e31ab,7445454c2af244f03b9274db12e3e4dd325e31ab,7445454c2af244f03b9274db12e3e4dd325e31ab,5387c90b329308daf6309c3cbf2417fe7502d9f4,7445454c2af244f03b9274db12e3e4dd325e31ab,7445454c2af244f03b9274db12e3e4dd325e31ab,7445454c2af244f03b9274db12e3e4dd325e31ab,1855d3892b15f82eb4aeed0eb9ae05bb938feea4..0ffb1cf17e0b2e6687b1c5ff12ff87405e2552b6
@@@@@@@@@ -1063,6 -1063,6 -1063,6 -1063,7 -1063,6 -1063,6 -1063,6 -1063,6 +1063,7 @@@@@@@@@ int arm_smmu_write_ctx_desc(struct arm_
                bool cd_live;
                __le64 *cdptr;
                struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
+++ ++++        struct arm_smmu_device *smmu = master->smmu;
        
                if (WARN_ON(ssid >= (1 << cd_table->s1cdmax)))
                        return -E2BIG;
                if (!cd) { /* (5) */
                        val = 0;
                } else if (cd == &quiet_cd) { /* (4) */
+++ ++++                if (!(smmu->features & ARM_SMMU_FEAT_STALL_FORCE))
+++ ++++                        val &= ~(CTXDESC_CD_0_S | CTXDESC_CD_0_R);
                        val |= CTXDESC_CD_0_TCR_EPD0;
                } else if (cd_live) { /* (3) */
                        val &= ~CTXDESC_CD_0_ASID;
@@@@@@@@@ -1249,7 -1249,7 -1249,7 -1252,7 -1249,7 -1249,7 -1249,7 -1249,7 +1252,7 @@@@@@@@@ static void arm_smmu_sync_ste_for_sid(s
        }
        
        static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
--- ----                                      __le64 *dst)
+++ ++++                                      struct arm_smmu_ste *dst)
        {
                /*
                 * This is hideously complicated, but we only really care about
                 * 2. Write everything apart from dword 0, sync, write dword 0, sync
                 * 3. Update Config, sync
                 */
--- ----        u64 val = le64_to_cpu(dst[0]);
+++ ++++        u64 val = le64_to_cpu(dst->data[0]);
                bool ste_live = false;
--- ----        struct arm_smmu_device *smmu = NULL;
+++ ++++        struct arm_smmu_device *smmu = master->smmu;
                struct arm_smmu_ctx_desc_cfg *cd_table = NULL;
                struct arm_smmu_s2_cfg *s2_cfg = NULL;
--- ----        struct arm_smmu_domain *smmu_domain = NULL;
+++ ++++        struct arm_smmu_domain *smmu_domain = master->domain;
                struct arm_smmu_cmdq_ent prefetch_cmd = {
                        .opcode         = CMDQ_OP_PREFETCH_CFG,
                        .prefetch       = {
                        },
                };
        
--- ----        if (master) {
--- ----                smmu_domain = master->domain;
--- ----                smmu = master->smmu;
--- ----        }
--- ----
                if (smmu_domain) {
                        switch (smmu_domain->stage) {
                        case ARM_SMMU_DOMAIN_S1:
                                cd_table = &master->cd_table;
                                break;
                        case ARM_SMMU_DOMAIN_S2:
--- ----                case ARM_SMMU_DOMAIN_NESTED:
                                s2_cfg = &smmu_domain->s2_cfg;
                                break;
                        default:
                        else
                                val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
        
--- ----                dst[0] = cpu_to_le64(val);
--- ----                dst[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
+++ ++++                dst->data[0] = cpu_to_le64(val);
+++ ++++                dst->data[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
                                                        STRTAB_STE_1_SHCFG_INCOMING));
--- ----                dst[2] = 0; /* Nuke the VMID */
+++ ++++                dst->data[2] = 0; /* Nuke the VMID */
                        /*
                         * The SMMU can perform negative caching, so we must sync
                         * the STE regardless of whether the old value was live.
                                STRTAB_STE_1_STRW_EL2 : STRTAB_STE_1_STRW_NSEL1;
        
                        BUG_ON(ste_live);
--- ----                dst[1] = cpu_to_le64(
+++ ++++                dst->data[1] = cpu_to_le64(
                                 FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
                                 FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
                                 FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
        
                        if (smmu->features & ARM_SMMU_FEAT_STALLS &&
                            !master->stall_enabled)
--- ----                        dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
+++ ++++                        dst->data[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
        
                        val |= (cd_table->cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
                                FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
        
                if (s2_cfg) {
                        BUG_ON(ste_live);
--- ----                dst[2] = cpu_to_le64(
+++ ++++                dst->data[2] = cpu_to_le64(
                                 FIELD_PREP(STRTAB_STE_2_S2VMID, s2_cfg->vmid) |
                                 FIELD_PREP(STRTAB_STE_2_VTCR, s2_cfg->vtcr) |
        #ifdef __BIG_ENDIAN
                                 STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2AA64 |
                                 STRTAB_STE_2_S2R);
        
--- ----                dst[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
+++ ++++                dst->data[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
        
                        val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS);
                }
        
                if (master->ats_enabled)
--- ----                dst[1] |= cpu_to_le64(FIELD_PREP(STRTAB_STE_1_EATS,
+++ ++++                dst->data[1] |= cpu_to_le64(FIELD_PREP(STRTAB_STE_1_EATS,
                                                         STRTAB_STE_1_EATS_TRANS));
        
                arm_smmu_sync_ste_for_sid(smmu, sid);
                /* See comment in arm_smmu_write_ctx_desc() */
--- ----        WRITE_ONCE(dst[0], cpu_to_le64(val));
+++ ++++        WRITE_ONCE(dst->data[0], cpu_to_le64(val));
                arm_smmu_sync_ste_for_sid(smmu, sid);
        
                /* It's likely that we'll want to use the new STE soon */
                        arm_smmu_cmdq_issue_cmd(smmu, &prefetch_cmd);
        }
        
--- ----static void arm_smmu_init_bypass_stes(__le64 *strtab, unsigned int nent, bool force)
+++ ++++static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,
+++ ++++                                      unsigned int nent, bool force)
        {
                unsigned int i;
                u64 val = STRTAB_STE_0_V;
                        val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
        
                for (i = 0; i < nent; ++i) {
--- ----                strtab[0] = cpu_to_le64(val);
--- ----                strtab[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
--- ----                                                   STRTAB_STE_1_SHCFG_INCOMING));
--- ----                strtab[2] = 0;
--- ----                strtab += STRTAB_STE_DWORDS;
+++ ++++                strtab->data[0] = cpu_to_le64(val);
+++ ++++                strtab->data[1] = cpu_to_le64(FIELD_PREP(
+++ ++++                        STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING));
+++ ++++                strtab->data[2] = 0;
+++ ++++                strtab++;
                }
        }
        
@@@@@@@@@ -2171,7 -2171,7 -2171,7 -2169,6 -2171,7 -2171,7 -2171,7 -2171,7 +2169,6 @@@@@@@@@ static int arm_smmu_domain_finalise(str
                        fmt = ARM_64_LPAE_S1;
                        finalise_stage_fn = arm_smmu_domain_finalise_s1;
                        break;
--- ----        case ARM_SMMU_DOMAIN_NESTED:
                case ARM_SMMU_DOMAIN_S2:
                        ias = smmu->ias;
                        oas = smmu->oas;
                return 0;
        }
        
--- ----static __le64 *arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
+++ ++++static struct arm_smmu_ste *
+++ ++++arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
        {
--- ----        __le64 *step;
                struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
        
                if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
--- ----                struct arm_smmu_strtab_l1_desc *l1_desc;
--- ----                int idx;
+++ ++++                unsigned int idx1, idx2;
        
                        /* Two-level walk */
--- ----                idx = (sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS;
--- ----                l1_desc = &cfg->l1_desc[idx];
--- ----                idx = (sid & ((1 << STRTAB_SPLIT) - 1)) * STRTAB_STE_DWORDS;
--- ----                step = &l1_desc->l2ptr[idx];
+++ ++++                idx1 = (sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS;
+++ ++++                idx2 = sid & ((1 << STRTAB_SPLIT) - 1);
+++ ++++                return &cfg->l1_desc[idx1].l2ptr[idx2];
                } else {
                        /* Simple linear lookup */
--- ----                step = &cfg->strtab[sid * STRTAB_STE_DWORDS];
+++ ++++                return (struct arm_smmu_ste *)&cfg
+++ ++++                               ->strtab[sid * STRTAB_STE_DWORDS];
                }
--- ----
--- ----        return step;
        }
        
        static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
        
                for (i = 0; i < master->num_streams; ++i) {
                        u32 sid = master->streams[i].id;
--- ----                __le64 *step = arm_smmu_get_step_for_sid(smmu, sid);
+++ ++++                struct arm_smmu_ste *step =
+++ ++++                        arm_smmu_get_step_for_sid(smmu, sid);
        
                        /* Bridged PCI devices may end up with duplicated IDs */
                        for (j = 0; j < i; j++)
@@@@@@@@@ -2649,9 -2649,9 -2649,9 -2644,9 -2649,9 -2649,9 -2649,9 -2649,6 +2644,6 @@@@@@@@@ static struct iommu_device *arm_smmu_pr
                struct arm_smmu_master *master;
                struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
        
-------         if (!fwspec || fwspec->ops != &arm_smmu_ops)
-------                 return ERR_PTR(-ENODEV);
------- 
                if (WARN_ON_ONCE(dev_iommu_priv_get(dev)))
                        return ERR_PTR(-EBUSY);
        
        
        err_free_master:
                kfree(master);
-------         dev_iommu_priv_set(dev, NULL);
                return ERR_PTR(ret);
        }
        
@@@@@@@@@ -2742,7 -2742,7 -2742,7 -2737,7 -2742,7 -2742,7 -2742,7 -2738,7 +2733,7 @@@@@@@@@ static int arm_smmu_enable_nesting(stru
                if (smmu_domain->smmu)
                        ret = -EPERM;
                else
--- ----                smmu_domain->stage = ARM_SMMU_DOMAIN_NESTED;
+++ ++++                smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
                mutex_unlock(&smmu_domain->init_mutex);
        
                return ret;
@@@@@@@@@ -3769,7 -3769,7 -3769,7 -3764,7 -3769,7 -3769,7 -3769,7 -3765,7 +3760,7 @@@@@@@@@ static void arm_smmu_rmr_install_bypass
                iort_get_rmr_sids(dev_fwnode(smmu->dev), &rmr_list);
        
                list_for_each_entry(e, &rmr_list, list) {
--- ----                __le64 *step;
+++ ++++                struct arm_smmu_ste *step;
                        struct iommu_iort_rmr_data *rmr;
                        int ret, i;
        
index d6d1a2a55cc0692fb02f0f58b901ac438c71604c,d6d1a2a55cc0692fb02f0f58b901ac438c71604c,d6d1a2a55cc0692fb02f0f58b901ac438c71604c,b0a6b367d8a2c02558fdcaa1fde6ed66717d9ac7,d6d1a2a55cc0692fb02f0f58b901ac438c71604c,d6d1a2a55cc0692fb02f0f58b901ac438c71604c,d6d1a2a55cc0692fb02f0f58b901ac438c71604c,adc7937fd8a3a3774002da551a109bd0373d8700..68b6bc5e7c71016b8d58a6a077e921b27fb51447
@@@@@@@@@ -82,6 -82,6 -82,6 -82,23 -82,6 -82,6 -82,6 -82,6 +82,23 @@@@@@@@@ static inline void arm_smmu_rpm_put(str
                        pm_runtime_put_autosuspend(smmu->dev);
        }
        
+++ ++++static void arm_smmu_rpm_use_autosuspend(struct arm_smmu_device *smmu)
+++ ++++{
+++ ++++        /*
+++ ++++         * Setup an autosuspend delay to avoid bouncing runpm state.
+++ ++++         * Otherwise, if a driver for a suspended consumer device
+++ ++++         * unmaps buffers, it will runpm resume/suspend for each one.
+++ ++++         *
+++ ++++         * For example, when used by a GPU device, when an application
+++ ++++         * or game exits, it can trigger unmapping 100s or 1000s of
+++ ++++         * buffers.  With a runpm cycle for each buffer, that adds up
+++ ++++         * to 5-10sec worth of reprogramming the context bank, while
+++ ++++         * the system appears to be locked up to the user.
+++ ++++         */
+++ ++++        pm_runtime_set_autosuspend_delay(smmu->dev, 20);
+++ ++++        pm_runtime_use_autosuspend(smmu->dev);
+++ ++++}
+++ ++++
        static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
        {
                return container_of(dom, struct arm_smmu_domain, domain);
@@@@@@@@@ -392,8 -392,8 -392,8 -409,7 -392,8 -392,8 -392,8 -392,8 +409,7 @@@@@@@@@ static irqreturn_t arm_smmu_context_fau
        {
                u32 fsr, fsynr, cbfrsynra;
                unsigned long iova;
--- ----        struct iommu_domain *domain = dev;
--- ----        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+++ ++++        struct arm_smmu_domain *smmu_domain = dev;
                struct arm_smmu_device *smmu = smmu_domain->smmu;
                int idx = smmu_domain->cfg.cbndx;
                int ret;
                iova = arm_smmu_cb_readq(smmu, idx, ARM_SMMU_CB_FAR);
                cbfrsynra = arm_smmu_gr1_read(smmu, ARM_SMMU_GR1_CBFRSYNRA(idx));
        
--- ----        ret = report_iommu_fault(domain, NULL, iova,
+++ ++++        ret = report_iommu_fault(&smmu_domain->domain, NULL, iova,
                        fsynr & ARM_SMMU_FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ);
        
                if (ret == -ENOSYS)
@@@@@@@@@ -607,7 -607,7 -607,7 -623,7 -607,7 -607,7 -607,7 -607,7 +623,7 @@@@@@@@@ static int arm_smmu_alloc_context_bank(
                return __arm_smmu_alloc_bitmap(smmu->context_map, start, smmu->num_context_banks);
        }
        
--- ----static int arm_smmu_init_domain_context(struct iommu_domain *domain,
+++ ++++static int arm_smmu_init_domain_context(struct arm_smmu_domain *smmu_domain,
                                                struct arm_smmu_device *smmu,
                                                struct device *dev)
        {
                struct io_pgtable_ops *pgtbl_ops;
                struct io_pgtable_cfg pgtbl_cfg;
                enum io_pgtable_fmt fmt;
--- ----        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+++ ++++        struct iommu_domain *domain = &smmu_domain->domain;
                struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
                irqreturn_t (*context_fault)(int irq, void *dev);
        
                if (smmu_domain->smmu)
                        goto out_unlock;
        
--- ----        if (domain->type == IOMMU_DOMAIN_IDENTITY) {
--- ----                smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
--- ----                smmu_domain->smmu = smmu;
--- ----                goto out_unlock;
--- ----        }
--- ----
                /*
                 * Mapping the requested stage onto what we support is surprisingly
                 * complicated, mainly because the spec allows S1+S2 SMMUs without
                else
                        context_fault = arm_smmu_context_fault;
        
--- ----        ret = devm_request_irq(smmu->dev, irq, context_fault,
--- ----                               IRQF_SHARED, "arm-smmu-context-fault", domain);
+++ ++++        ret = devm_request_irq(smmu->dev, irq, context_fault, IRQF_SHARED,
+++ ++++                               "arm-smmu-context-fault", smmu_domain);
                if (ret < 0) {
                        dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
                                cfg->irptndx, irq);
                return ret;
        }
        
--- ----static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
+++ ++++static void arm_smmu_destroy_domain_context(struct arm_smmu_domain *smmu_domain)
        {
--- ----        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
                struct arm_smmu_device *smmu = smmu_domain->smmu;
                struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
                int ret, irq;
        
--- ----        if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
+++ ++++        if (!smmu)
                        return;
        
                ret = arm_smmu_rpm_get(smmu);
        
                if (cfg->irptndx != ARM_SMMU_INVALID_IRPTNDX) {
                        irq = smmu->irqs[cfg->irptndx];
--- ----                devm_free_irq(smmu->dev, irq, domain);
+++ ++++                devm_free_irq(smmu->dev, irq, smmu_domain);
                }
        
                free_io_pgtable_ops(smmu_domain->pgtbl_ops);
                arm_smmu_rpm_put(smmu);
        }
        
--- ----static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
+++ ++++static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
        {
                struct arm_smmu_domain *smmu_domain;
        
--- ----        if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_IDENTITY) {
--- ----                if (using_legacy_binding || type != IOMMU_DOMAIN_DMA)
--- ----                        return NULL;
--- ----        }
                /*
                 * Allocate the domain and initialise some of its data structures.
                 * We can't really do anything meaningful until we've added a
                mutex_init(&smmu_domain->init_mutex);
                spin_lock_init(&smmu_domain->cb_lock);
        
+++ ++++        if (dev) {
+++ ++++                struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
+++ ++++
+++ ++++                if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
+++ ++++                        kfree(smmu_domain);
+++ ++++                        return NULL;
+++ ++++                }
+++ ++++        }
+++ ++++
                return &smmu_domain->domain;
        }
        
@@@@@@@@@ -881,7 -881,7 -881,7 -895,7 -881,7 -881,7 -881,7 -881,7 +895,7 @@@@@@@@@ static void arm_smmu_domain_free(struc
                 * Free the domain resources. We assume that all devices have
                 * already been detached.
                 */
--- ----        arm_smmu_destroy_domain_context(domain);
+++ ++++        arm_smmu_destroy_domain_context(smmu_domain);
                kfree(smmu_domain);
        }
        
@@@@@@@@@ -1081,21 -1081,21 -1081,21 -1095,14 -1081,21 -1081,21 -1081,21 -1081,21 +1095,14 @@@@@@@@@ static void arm_smmu_master_free_smes(s
                mutex_unlock(&smmu->stream_map_mutex);
        }
        
--- ----static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
--- ----                                      struct arm_smmu_master_cfg *cfg,
--- ----                                      struct iommu_fwspec *fwspec)
+++ ++++static void arm_smmu_master_install_s2crs(struct arm_smmu_master_cfg *cfg,
+++ ++++                                          enum arm_smmu_s2cr_type type,
+++ ++++                                          u8 cbndx, struct iommu_fwspec *fwspec)
        {
--- ----        struct arm_smmu_device *smmu = smmu_domain->smmu;
+++ ++++        struct arm_smmu_device *smmu = cfg->smmu;
                struct arm_smmu_s2cr *s2cr = smmu->s2crs;
--- ----        u8 cbndx = smmu_domain->cfg.cbndx;
--- ----        enum arm_smmu_s2cr_type type;
                int i, idx;
        
--- ----        if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS)
--- ----                type = S2CR_TYPE_BYPASS;
--- ----        else
--- ----                type = S2CR_TYPE_TRANS;
--- ----
                for_each_cfg_sme(cfg, fwspec, i, idx) {
                        if (type == s2cr[idx].type && cbndx == s2cr[idx].cbndx)
                                continue;
                        s2cr[idx].cbndx = cbndx;
                        arm_smmu_write_s2cr(smmu, idx);
                }
--- ----        return 0;
        }
        
        static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
                struct arm_smmu_device *smmu;
                int ret;
        
-------         if (!fwspec || fwspec->ops != &arm_smmu_ops) {
-------                 dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
-------                 return -ENXIO;
-------         }
------- 
                /*
                 * FIXME: The arch/arm DMA API code tries to attach devices to its own
                 * domains between of_xlate() and probe_device() - we have no way to cope
                        return ret;
        
                /* Ensure that the domain is finalised */
--- ----        ret = arm_smmu_init_domain_context(domain, smmu, dev);
+++ ++++        ret = arm_smmu_init_domain_context(smmu_domain, smmu, dev);
                if (ret < 0)
                        goto rpm_put;
        
                }
        
                /* Looks ok, so add the device to the domain */
--- ----        ret = arm_smmu_domain_add_master(smmu_domain, cfg, fwspec);
--- ----
--- ----        /*
--- ----         * Setup an autosuspend delay to avoid bouncing runpm state.
--- ----         * Otherwise, if a driver for a suspended consumer device
--- ----         * unmaps buffers, it will runpm resume/suspend for each one.
--- ----         *
--- ----         * For example, when used by a GPU device, when an application
--- ----         * or game exits, it can trigger unmapping 100s or 1000s of
--- ----         * buffers.  With a runpm cycle for each buffer, that adds up
--- ----         * to 5-10sec worth of reprogramming the context bank, while
--- ----         * the system appears to be locked up to the user.
--- ----         */
--- ----        pm_runtime_set_autosuspend_delay(smmu->dev, 20);
--- ----        pm_runtime_use_autosuspend(smmu->dev);
--- ----
+++ ++++        arm_smmu_master_install_s2crs(cfg, S2CR_TYPE_TRANS,
+++ ++++                                      smmu_domain->cfg.cbndx, fwspec);
+++ ++++        arm_smmu_rpm_use_autosuspend(smmu);
        rpm_put:
                arm_smmu_rpm_put(smmu);
                return ret;
        }
        
+++ ++++static int arm_smmu_attach_dev_type(struct device *dev,
+++ ++++                                    enum arm_smmu_s2cr_type type)
+++ ++++{
+++ ++++        struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
+++ ++++        struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+++ ++++        struct arm_smmu_device *smmu;
+++ ++++        int ret;
+++ ++++
+++ ++++        if (!cfg)
+++ ++++                return -ENODEV;
+++ ++++        smmu = cfg->smmu;
+++ ++++
+++ ++++        ret = arm_smmu_rpm_get(smmu);
+++ ++++        if (ret < 0)
+++ ++++                return ret;
+++ ++++
+++ ++++        arm_smmu_master_install_s2crs(cfg, type, 0, fwspec);
+++ ++++        arm_smmu_rpm_use_autosuspend(smmu);
+++ ++++        arm_smmu_rpm_put(smmu);
+++ ++++        return 0;
+++ ++++}
+++ ++++
+++ ++++static int arm_smmu_attach_dev_identity(struct iommu_domain *domain,
+++ ++++                                        struct device *dev)
+++ ++++{
+++ ++++        return arm_smmu_attach_dev_type(dev, S2CR_TYPE_BYPASS);
+++ ++++}
+++ ++++
+++ ++++static const struct iommu_domain_ops arm_smmu_identity_ops = {
+++ ++++        .attach_dev = arm_smmu_attach_dev_identity,
+++ ++++};
+++ ++++
+++ ++++static struct iommu_domain arm_smmu_identity_domain = {
+++ ++++        .type = IOMMU_DOMAIN_IDENTITY,
+++ ++++        .ops = &arm_smmu_identity_ops,
+++ ++++};
+++ ++++
+++ ++++static int arm_smmu_attach_dev_blocked(struct iommu_domain *domain,
+++ ++++                                       struct device *dev)
+++ ++++{
+++ ++++        return arm_smmu_attach_dev_type(dev, S2CR_TYPE_FAULT);
+++ ++++}
+++ ++++
+++ ++++static const struct iommu_domain_ops arm_smmu_blocked_ops = {
+++ ++++        .attach_dev = arm_smmu_attach_dev_blocked,
+++ ++++};
+++ ++++
+++ ++++static struct iommu_domain arm_smmu_blocked_domain = {
+++ ++++        .type = IOMMU_DOMAIN_BLOCKED,
+++ ++++        .ops = &arm_smmu_blocked_ops,
+++ ++++};
+++ ++++
        static int arm_smmu_map_pages(struct iommu_domain *domain, unsigned long iova,
                                      phys_addr_t paddr, size_t pgsize, size_t pgcount,
                                      int prot, gfp_t gfp, size_t *mapped)
@@@@@@@@@ -1357,10 -1357,10 -1357,10 -1402,10 -1357,10 -1357,10 -1357,10 -1352,8 +1397,8 @@@@@@@@@ static struct iommu_device *arm_smmu_pr
                        fwspec = dev_iommu_fwspec_get(dev);
                        if (ret)
                                goto out_free;
-------         } else if (fwspec && fwspec->ops == &arm_smmu_ops) {
-------                 smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
                } else {
-------                 return ERR_PTR(-ENODEV);
+++++++                 smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
                }
        
                ret = -EINVAL;
@@@@@@@@@ -1427,7 -1427,7 -1427,7 -1472,7 -1427,7 -1427,7 -1427,7 -1420,6 +1465,6 @@@@@@@@@ static void arm_smmu_release_device(str
        
                arm_smmu_rpm_put(cfg->smmu);
        
-------         dev_iommu_priv_set(dev, NULL);
                kfree(cfg);
        }
        
@@@@@@@@@ -1560,8 -1560,8 -1560,8 -1605,10 -1560,8 -1560,8 -1560,8 -1552,8 +1597,10 @@@@@@@@@ static int arm_smmu_def_domain_type(str
        }
        
        static struct iommu_ops arm_smmu_ops = {
+++ ++++        .identity_domain        = &arm_smmu_identity_domain,
+++ ++++        .blocked_domain         = &arm_smmu_blocked_domain,
                .capable                = arm_smmu_capable,
--- ----        .domain_alloc           = arm_smmu_domain_alloc,
+++ ++++        .domain_alloc_paging    = arm_smmu_domain_alloc_paging,
                .probe_device           = arm_smmu_probe_device,
                .release_device         = arm_smmu_release_device,
                .probe_finalize         = arm_smmu_probe_finalize,
@@@@@@@@@ -2161,7 -2161,7 -2161,7 -2208,7 -2161,7 -2161,7 -2161,7 -2153,8 +2200,8 @@@@@@@@@ static int arm_smmu_device_probe(struc
                        return err;
                }
        
-------         err = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev);
+++++++         err = iommu_device_register(&smmu->iommu, &arm_smmu_ops,
+++++++                                     using_legacy_binding ? NULL : dev);
                if (err) {
                        dev_err(dev, "Failed to register iommu\n");
                        iommu_device_sysfs_remove(&smmu->iommu);
index 97b2122032b2371915047aa03d3118005fc49496,97b2122032b2371915047aa03d3118005fc49496,97b2122032b2371915047aa03d3118005fc49496,67abeb02cf536b443f92dbab83a0443bee01a6a3,97b2122032b2371915047aa03d3118005fc49496,97b2122032b2371915047aa03d3118005fc49496,97b2122032b2371915047aa03d3118005fc49496,33f3c870086cea64b3fbcf270d66a02336136917..17a1c163fef660397f9e39f252563952cf9bd10a
@@@@@@@@@ -79,16 -79,16 -79,16 -79,16 -79,16 -79,16 -79,16 -79,6 +79,6 @@@@@@@@@ static struct qcom_iommu_domain *to_qco
        
        static const struct iommu_ops qcom_iommu_ops;
        
------- static struct qcom_iommu_dev * to_iommu(struct device *dev)
------- {
-------         struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
------- 
-------         if (!fwspec || fwspec->ops != &qcom_iommu_ops)
-------                 return NULL;
------- 
-------         return dev_iommu_priv_get(dev);
------- }
------- 
        static struct qcom_iommu_ctx * to_ctx(struct qcom_iommu_domain *d, unsigned asid)
        {
                struct qcom_iommu_dev *qcom_iommu = d->iommu;
@@@@@@@@@ -372,7 -372,7 -372,7 -372,7 -372,7 -372,7 -372,7 -362,7 +362,7 @@@@@@@@@ static void qcom_iommu_domain_free(stru
        
        static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
        {
-------         struct qcom_iommu_dev *qcom_iommu = to_iommu(dev);
+++++++         struct qcom_iommu_dev *qcom_iommu = dev_iommu_priv_get(dev);
                struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
                int ret;
        
@@@@@@@@@ -404,7 -404,7 -404,7 -404,7 -404,7 -404,7 -404,7 -394,7 +394,7 @@@@@@@@@ static int qcom_iommu_identity_attach(s
                struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
                struct qcom_iommu_domain *qcom_domain;
                struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-------         struct qcom_iommu_dev *qcom_iommu = to_iommu(dev);
+++++++         struct qcom_iommu_dev *qcom_iommu = dev_iommu_priv_get(dev);
                unsigned int i;
        
                if (domain == identity_domain || !domain)
@@@@@@@@@ -535,7 -535,7 -535,7 -535,7 -535,7 -535,7 -535,7 -525,7 +525,7 @@@@@@@@@ static bool qcom_iommu_capable(struct d
        
        static struct iommu_device *qcom_iommu_probe_device(struct device *dev)
        {
-------         struct qcom_iommu_dev *qcom_iommu = to_iommu(dev);
+++++++         struct qcom_iommu_dev *qcom_iommu = dev_iommu_priv_get(dev);
                struct device_link *link;
        
                if (!qcom_iommu)
@@@@@@@@@ -900,8 -900,8 -900,8 -900,16 -900,8 -900,8 -900,8 -890,8 +890,16 @@@@@@@@@ static void qcom_iommu_device_remove(st
        static int __maybe_unused qcom_iommu_resume(struct device *dev)
        {
                struct qcom_iommu_dev *qcom_iommu = dev_get_drvdata(dev);
+++ ++++        int ret;
+++ ++++
+++ ++++        ret = clk_bulk_prepare_enable(CLK_NUM, qcom_iommu->clks);
+++ ++++        if (ret < 0)
+++ ++++                return ret;
+++ ++++
+++ ++++        if (dev->pm_domain)
+++ ++++                return qcom_scm_restore_sec_cfg(qcom_iommu->sec_id, 0);
        
--- ----        return clk_bulk_prepare_enable(CLK_NUM, qcom_iommu->clks);
+++ ++++        return ret;
        }
        
        static int __maybe_unused qcom_iommu_suspend(struct device *dev)
index 897159dba47de4f863f57b365bd025cda0c8cd57,3531b956556c7df268ee32a5053a755d5ce0630b,3531b956556c7df268ee32a5053a755d5ce0630b,3531b956556c7df268ee32a5053a755d5ce0630b,3531b956556c7df268ee32a5053a755d5ce0630b,dc23a1a49c80f6d4499913b84a5eb5fa61648d94,3531b956556c7df268ee32a5053a755d5ce0630b,511589341074f094a2ff497da605b6d0aee7012e..6fb5f6fceea11fb7865d92d8451a5de98a655556
        
        #define DEFAULT_DOMAIN_ADDRESS_WIDTH 57
        
----- --#define MAX_AGAW_WIDTH 64
----- --#define MAX_AGAW_PFN_WIDTH      (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
----- --
        #define __DOMAIN_MAX_PFN(gaw)  ((((uint64_t)1) << ((gaw) - VTD_PAGE_SHIFT)) - 1)
        #define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << (gaw)) - 1)
        
        
        #define IOVA_PFN(addr)          ((addr) >> PAGE_SHIFT)
        
----- --/* page table handling */
----- --#define LEVEL_STRIDE            (9)
----- --#define LEVEL_MASK              (((u64)1 << LEVEL_STRIDE) - 1)
----- --
----- --static inline int agaw_to_level(int agaw)
----- --{
----- --        return agaw + 2;
----- --}
----- --
----- --static inline int agaw_to_width(int agaw)
----- --{
----- --        return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH);
----- --}
----- --
----- --static inline int width_to_agaw(int width)
----- --{
----- --        return DIV_ROUND_UP(width - 30, LEVEL_STRIDE);
----- --}
----- --
----- --static inline unsigned int level_to_offset_bits(int level)
----- --{
----- --        return (level - 1) * LEVEL_STRIDE;
----- --}
----- --
----- --static inline int pfn_level_offset(u64 pfn, int level)
----- --{
----- --        return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
----- --}
----- --
----- --static inline u64 level_mask(int level)
----- --{
----- --        return -1ULL << level_to_offset_bits(level);
----- --}
----- --
----- --static inline u64 level_size(int level)
----- --{
----- --        return 1ULL << level_to_offset_bits(level);
----- --}
----- --
----- --static inline u64 align_to_level(u64 pfn, int level)
----- --{
----- --        return (pfn + level_size(level) - 1) & level_mask(level);
----- --}
----- --
----- --static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
----- --{
----- --        return 1UL << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
----- --}
----- --
----- --/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
----- --   are never going to work. */
----- --static inline unsigned long mm_to_dma_pfn_start(unsigned long mm_pfn)
----- --{
----- --        return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT);
----- --}
----- --static inline unsigned long mm_to_dma_pfn_end(unsigned long mm_pfn)
----- --{
----- --        return ((mm_pfn + 1) << (PAGE_SHIFT - VTD_PAGE_SHIFT)) - 1;
----- --}
----- --static inline unsigned long page_to_dma_pfn(struct page *pg)
----- --{
----- --        return mm_to_dma_pfn_start(page_to_pfn(pg));
----- --}
----- --static inline unsigned long virt_to_dma_pfn(void *p)
----- --{
----- --        return page_to_dma_pfn(virt_to_page(p));
----- --}
----- --
        static void __init check_tylersburg_isoch(void);
        static int rwbf_quirk;
        
@@@@@@@@@ -168,78 -168,78 -168,78 -168,78 -168,78 -97,6 -168,78 -168,78 +97,6 @@@@@@@@@ static phys_addr_t root_entry_uctp(stru
                return re->hi & VTD_PAGE_MASK;
        }
        
----- --static inline void context_set_present(struct context_entry *context)
----- --{
----- --        context->lo |= 1;
----- --}
----- --
----- --static inline void context_set_fault_enable(struct context_entry *context)
----- --{
----- --        context->lo &= (((u64)-1) << 2) | 1;
----- --}
----- --
----- --static inline void context_set_translation_type(struct context_entry *context,
----- --                                                unsigned long value)
----- --{
----- --        context->lo &= (((u64)-1) << 4) | 3;
----- --        context->lo |= (value & 3) << 2;
----- --}
----- --
----- --static inline void context_set_address_root(struct context_entry *context,
----- --                                            unsigned long value)
----- --{
----- --        context->lo &= ~VTD_PAGE_MASK;
----- --        context->lo |= value & VTD_PAGE_MASK;
----- --}
----- --
----- --static inline void context_set_address_width(struct context_entry *context,
----- --                                             unsigned long value)
----- --{
----- --        context->hi |= value & 7;
----- --}
----- --
----- --static inline void context_set_domain_id(struct context_entry *context,
----- --                                         unsigned long value)
----- --{
----- --        context->hi |= (value & ((1 << 16) - 1)) << 8;
----- --}
----- --
----- --static inline void context_set_pasid(struct context_entry *context)
----- --{
----- --        context->lo |= CONTEXT_PASIDE;
----- --}
----- --
----- --static inline int context_domain_id(struct context_entry *c)
----- --{
----- --        return((c->hi >> 8) & 0xffff);
----- --}
----- --
----- --static inline void context_clear_entry(struct context_entry *context)
----- --{
----- --        context->lo = 0;
----- --        context->hi = 0;
----- --}
----- --
----- --static inline bool context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
----- --{
----- --        if (!iommu->copied_tables)
----- --                return false;
----- --
----- --        return test_bit(((long)bus << 8) | devfn, iommu->copied_tables);
----- --}
----- --
----- --static inline void
----- --set_context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
----- --{
----- --        set_bit(((long)bus << 8) | devfn, iommu->copied_tables);
----- --}
----- --
----- --static inline void
----- --clear_context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
----- --{
----- --        clear_bit(((long)bus << 8) | devfn, iommu->copied_tables);
----- --}
----- --
        /*
         * This domain is a statically identity mapping domain.
         *      1. This domain creats a static 1:1 mapping to all usable memory.
@@@@@@@@@ -299,7 -299,7 -299,7 -299,7 -299,7 -156,7 -299,7 -299,7 +156,7 @@@@@@@@@ static int iommu_skip_te_disable
        #define IDENTMAP_AZALIA         4
        
        const struct iommu_ops intel_iommu_ops;
 ------ const struct iommu_dirty_ops intel_dirty_ops;
 ++++++ static const struct iommu_dirty_ops intel_dirty_ops;
        
        static bool translation_pre_enabled(struct intel_iommu *iommu)
        {
@@@@@@@@@ -383,13 -383,13 -383,13 -383,13 -383,13 -240,12 -383,13 -383,13 +240,12 @@@@@@@@@ void free_pgtable_page(void *vaddr
                free_page((unsigned long)vaddr);
        }
        
----- --static inline int domain_type_is_si(struct dmar_domain *domain)
+++++ ++static int domain_type_is_si(struct dmar_domain *domain)
        {
                return domain->domain.type == IOMMU_DOMAIN_IDENTITY;
        }
        
----- --static inline int domain_pfn_supported(struct dmar_domain *domain,
----- --                                       unsigned long pfn)
+++++ ++static int domain_pfn_supported(struct dmar_domain *domain, unsigned long pfn)
        {
                int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
        
@@@@@@@@@ -451,7 -451,7 -451,7 -451,7 -451,7 -307,7 -451,7 -451,7 +307,7 @@@@@@@@@ int iommu_calculate_agaw(struct intel_i
                return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
        }
        
----- --static inline bool iommu_paging_structure_coherency(struct intel_iommu *iommu)
+++++ ++static bool iommu_paging_structure_coherency(struct intel_iommu *iommu)
        {
                return sm_supported(iommu) ?
                                ecap_smpwc(iommu->ecap) : ecap_coherent(iommu->ecap);
@@@@@@@@@ -703,7 -703,7 -703,7 -703,7 -703,7 -559,7 -703,7 -703,7 +559,7 @@@@@@@@@ static bool iommu_is_dummy(struct intel
                return false;
        }
        
----- --struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
+++++ ++static struct intel_iommu *device_lookup_iommu(struct device *dev, u8 *bus, u8 *devfn)
        {
                struct dmar_drhd_unit *drhd = NULL;
                struct pci_dev *pdev = NULL;
@@@@@@@@@ -1574,9 -1574,9 -1574,9 -1574,9 -1574,9 -1430,8 -1574,9 -1574,9 +1430,8 @@@@@@@@@ static void iommu_flush_iotlb_psi(struc
        }
        
        /* Notification for newly created mappings */
----- --static inline void __mapping_notify_one(struct intel_iommu *iommu,
----- --                                        struct dmar_domain *domain,
----- --                                        unsigned long pfn, unsigned int pages)
+++++ ++static void __mapping_notify_one(struct intel_iommu *iommu, struct dmar_domain *domain,
+++++ ++                                 unsigned long pfn, unsigned int pages)
        {
                /*
                 * It's a non-present to present mapping. Only flush if caching mode
@@@@@@@@@ -1843,7 -1843,7 -1843,7 -1843,7 -1843,7 -1698,7 -1843,7 -1843,7 +1698,7 @@@@@@@@@ void domain_detach_iommu(struct dmar_do
                spin_unlock(&iommu->lock);
        }
        
----- --static inline int guestwidth_to_adjustwidth(int gaw)
+++++ ++static int guestwidth_to_adjustwidth(int gaw)
        {
                int agaw;
                int r = (gaw - 12) % 9;
@@@@@@@@@ -1877,7 -1877,7 -1877,7 -1877,7 -1877,7 -1732,7 -1877,7 -1877,7 +1732,7 @@@@@@@@@ static void domain_exit(struct dmar_dom
         * Value of X in the PDTS field of a scalable mode context entry
         * indicates PASID directory with 2^(X + 7) entries.
         */
----- --static inline unsigned long context_get_sm_pds(struct pasid_table *table)
+++++ ++static unsigned long context_get_sm_pds(struct pasid_table *table)
        {
                unsigned long pds, max_pde;
        
                return pds - 7;
        }
        
----- --/*
----- -- * Set the RID_PASID field of a scalable mode context entry. The
----- -- * IOMMU hardware will use the PASID value set in this field for
----- -- * DMA translations of DMA requests without PASID.
----- -- */
----- --static inline void
----- --context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasid)
----- --{
----- --        context->hi |= pasid & ((1 << 20) - 1);
----- --}
----- --
----- --/*
----- -- * Set the DTE(Device-TLB Enable) field of a scalable mode context
----- -- * entry.
----- -- */
----- --static inline void context_set_sm_dte(struct context_entry *context)
----- --{
----- --        context->lo |= BIT_ULL(2);
----- --}
----- --
----- --/*
----- -- * Set the PRE(Page Request Enable) field of a scalable mode context
----- -- * entry.
----- -- */
----- --static inline void context_set_sm_pre(struct context_entry *context)
----- --{
----- --        context->lo |= BIT_ULL(4);
----- --}
----- --
----- --/* Convert value to context PASID directory size field coding. */
----- --#define context_pdts(pds)       (((pds) & 0x7) << 9)
----- --
        static int domain_context_mapping_one(struct dmar_domain *domain,
                                              struct intel_iommu *iommu,
                                              struct pasid_table *table,
@@@@@@@@@ -2081,14 -2081,14 -2081,14 -2081,14 -2081,14 -1904,11 -2081,14 -2081,14 +1904,11 @@@@@@@@@ static int domain_context_mapping_cb(st
        static int
        domain_context_mapping(struct dmar_domain *domain, struct device *dev)
        {
+++++ ++        struct device_domain_info *info = dev_iommu_priv_get(dev);
                struct domain_context_mapping_data data;
+++++ ++        struct intel_iommu *iommu = info->iommu;
+++++ ++        u8 bus = info->bus, devfn = info->devfn;
                struct pasid_table *table;
----- --        struct intel_iommu *iommu;
----- --        u8 bus, devfn;
----- --
----- --        iommu = device_to_iommu(dev, &bus, &devfn);
----- --        if (!iommu)
----- --                return -ENODEV;
        
                table = intel_pasid_get_table(dev);
        
        }
        
        /* Returns a number of VTD pages, but aligned to MM page size */
----- --static inline unsigned long aligned_nrpages(unsigned long host_addr,
----- --                                            size_t size)
+++++ ++static unsigned long aligned_nrpages(unsigned long host_addr, size_t size)
        {
                host_addr &= ~PAGE_MASK;
                return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
        }
        
        /* Return largest possible superpage level for a given mapping */
----- --static inline int hardware_largepage_caps(struct dmar_domain *domain,
----- --                                          unsigned long iov_pfn,
----- --                                          unsigned long phy_pfn,
----- --                                          unsigned long pages)
+++++ ++static int hardware_largepage_caps(struct dmar_domain *domain, unsigned long iov_pfn,
+++++ ++                                   unsigned long phy_pfn, unsigned long pages)
        {
                int support, level = 1;
                unsigned long pfnmerge;
@@@@@@@@@ -2207,8 -2207,6 -2207,6 -2207,6 -2207,6 -2024,6 -2207,6 -2207,8 +2024,8 @@@@@@@@@ __domain_mapping(struct dmar_domain *do
                                attr |= DMA_FL_PTE_DIRTY;
                }
        
 ++++++         domain->has_mappings = true;
 ++++++ 
                pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr;
        
                while (nr_pages > 0) {
@@@@@@@@@ -2449,15 -2447,15 -2447,15 -2447,15 -2447,15 -2264,10 -2447,15 -2449,15 +2266,10 @@@@@@@@@ static int dmar_domain_attach_device(st
                                             struct device *dev)
        {
                struct device_domain_info *info = dev_iommu_priv_get(dev);
----- --        struct intel_iommu *iommu;
+++++ ++        struct intel_iommu *iommu = info->iommu;
                unsigned long flags;
----- --        u8 bus, devfn;
                int ret;
        
----- --        iommu = device_to_iommu(dev, &bus, &devfn);
----- --        if (!iommu)
----- --                return -ENODEV;
----- --
                ret = domain_attach_iommu(domain, iommu);
                if (ret)
                        return ret;
                if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
                        /* Setup the PASID entry for requests without PASID: */
                        if (hw_pass_through && domain_type_is_si(domain))
----- --                        ret = intel_pasid_setup_pass_through(iommu, domain,
+++++ ++                        ret = intel_pasid_setup_pass_through(iommu,
                                                dev, IOMMU_NO_PASID);
                        else if (domain->use_first_level)
                                ret = domain_setup_first_level(iommu, domain, dev,
                        return ret;
                }
        
 ------         iommu_enable_pci_caps(info);
 ++++++         if (sm_supported(info->iommu) || !domain_type_is_si(info->domain))
 ++++++                 iommu_enable_pci_caps(info);
        
                return 0;
        }
@@@@@@@@@ -3615,7 -3612,7 -3612,7 -3612,7 -3612,7 -3424,7 -3612,7 -3615,7 +3427,7 @@@@@@@@@ void intel_iommu_shutdown(void
                up_write(&dmar_global_lock);
        }
        
----- --static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
+++++ ++static struct intel_iommu *dev_to_intel_iommu(struct device *dev)
        {
                struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
        
@@@@@@@@@ -3694,7 -3691,7 -3691,7 -3691,7 -3691,7 -3503,7 -3691,7 -3694,7 +3506,7 @@@@@@@@@ const struct attribute_group *intel_iom
                NULL,
        };
        
----- --static inline bool has_external_pci(void)
+++++ ++static bool has_external_pci(void)
        {
                struct pci_dev *pdev = NULL;
        
@@@@@@@@@ -3928,8 -3925,8 -3925,8 -3925,8 -3925,8 -3737,8 -3925,8 -3928,8 +3740,8 @@@@@@@@@ static int domain_context_clear_one_cb(
         */
        static void domain_context_clear(struct device_domain_info *info)
        {
 ------         if (!info->iommu || !info->dev || !dev_is_pci(info->dev))
 ------                 return;
 ++++++         if (!dev_is_pci(info->dev))
 ++++++                 domain_context_clear_one(info, info->bus, info->devfn);
        
                pci_for_each_dma_alias(to_pci_dev(info->dev),
                                       &domain_context_clear_one_cb, info);
@@@@@@@@@ -4119,14 -4116,14 -4116,14 -4116,14 -4116,14 -3928,11 -4116,14 -4119,14 +3931,11 @@@@@@@@@ static void intel_iommu_domain_free(str
        int prepare_domain_attach_device(struct iommu_domain *domain,
                                         struct device *dev)
        {
+++++ ++        struct device_domain_info *info = dev_iommu_priv_get(dev);
                struct dmar_domain *dmar_domain = to_dmar_domain(domain);
----- --        struct intel_iommu *iommu;
+++++ ++        struct intel_iommu *iommu = info->iommu;
                int addr_width;
        
----- --        iommu = device_to_iommu(dev, NULL, NULL);
----- --        if (!iommu)
----- --                return -ENODEV;
----- --
                if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap))
                        return -EINVAL;
        
@@@@@@@@@ -4363,8 -4360,7 -4360,7 -4360,7 -4360,7 -4169,7 -4360,7 -4363,8 +4172,8 @@@@@@@@@ static bool intel_iommu_enforce_cache_c
                        return true;
        
                spin_lock_irqsave(&dmar_domain->lock, flags);
 ------         if (!domain_support_force_snooping(dmar_domain)) {
 ++++++         if (!domain_support_force_snooping(dmar_domain) ||
 ++++++             (!dmar_domain->use_first_level && dmar_domain->has_mappings)) {
                        spin_unlock_irqrestore(&dmar_domain->lock, flags);
                        return false;
                }
@@@@@@@@@ -4403,7 -4399,7 -4399,7 -4399,7 -4399,7 -4208,7 -4399,7 -4403,7 +4212,7 @@@@@@@@@ static struct iommu_device *intel_iommu
                u8 bus, devfn;
                int ret;
        
----- --        iommu = device_to_iommu(dev, &bus, &devfn);
+++++ ++        iommu = device_lookup_iommu(dev, &bus, &devfn);
                if (!iommu || !iommu->iommu.ops)
                        return ERR_PTR(-ENODEV);
        
                        ret = intel_pasid_alloc_table(dev);
                        if (ret) {
                                dev_err(dev, "PASID table allocation failed\n");
-------                         dev_iommu_priv_set(dev, NULL);
                                kfree(info);
                                return ERR_PTR(ret);
                        }
@@@@@@@@@ -4479,7 -4475,7 -4475,7 -4475,7 -4475,7 -4284,7 -4475,7 -4478,6 +4287,6 @@@@@@@@@ static void intel_iommu_release_device(
                dmar_remove_one_dev_info(dev);
                intel_pasid_free_table(dev);
                intel_iommu_debugfs_remove_dev(info);
-------         dev_iommu_priv_set(dev, NULL);
                kfree(info);
                set_dma_ops(dev, NULL);
        }
@@@@@@@@@ -4739,8 -4735,8 -4735,8 -4735,8 -4735,8 -4544,9 -4735,8 -4737,8 +4546,9 @@@@@@@@@ static int intel_iommu_iotlb_sync_map(s
        
        static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
        {
----- --        struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);
+++++ ++        struct device_domain_info *info = dev_iommu_priv_get(dev);
                struct dev_pasid_info *curr, *dev_pasid = NULL;
+++++ ++        struct intel_iommu *iommu = info->iommu;
                struct dmar_domain *dmar_domain;
                struct iommu_domain *domain;
                unsigned long flags;
@@@@@@@@@ -4811,8 -4807,8 -4807,8 -4807,8 -4807,8 -4617,7 -4807,8 -4809,8 +4619,7 @@@@@@@@@ static int intel_iommu_set_dev_pasid(st
                        goto out_free;
        
                if (domain_type_is_si(dmar_domain))
----- --                ret = intel_pasid_setup_pass_through(iommu, dmar_domain,
----- --                                                     dev, pasid);
+++++ ++                ret = intel_pasid_setup_pass_through(iommu, dev, pasid);
                else if (dmar_domain->use_first_level)
                        ret = domain_setup_first_level(iommu, dmar_domain,
                                                       dev, pasid);
@@@@@@@@@ -4929,7 -4925,7 -4925,7 -4925,7 -4925,7 -4734,7 -4925,7 -4927,7 +4736,7 @@@@@@@@@ static int intel_iommu_read_and_clear_d
                return 0;
        }
        
 ------ const struct iommu_dirty_ops intel_dirty_ops = {
 ++++++ static const struct iommu_dirty_ops intel_dirty_ops = {
                .set_dirty_tracking = intel_iommu_set_dirty_tracking,
                .read_and_clear_dirty = intel_iommu_read_and_clear_dirty,
        };
@@@@@@@@@ -5077,7 -5073,7 -5073,7 -5073,7 -5073,7 -4882,7 -5073,7 -5075,7 +4884,7 @@@@@@@@@ static void quirk_igfx_skip_te_disable(
                ver = (dev->device >> 8) & 0xff;
                if (ver != 0x45 && ver != 0x46 && ver != 0x4c &&
                    ver != 0x4e && ver != 0x8a && ver != 0x98 &&
 ------             ver != 0x9a && ver != 0xa7)
 ++++++             ver != 0x9a && ver != 0xa7 && ver != 0x7d)
                        return;
        
                if (risky_device(dev))
index ce030c5b5772abadabd3f4a11fb1e443ffe80599,65d37a138c75d48ccac9a3de4ea68573a1c1fc6b,65d37a138c75d48ccac9a3de4ea68573a1c1fc6b,65d37a138c75d48ccac9a3de4ea68573a1c1fc6b,65d37a138c75d48ccac9a3de4ea68573a1c1fc6b,0af1399836352b01050f865d636cf696dcbfa14e,65d37a138c75d48ccac9a3de4ea68573a1c1fc6b,ce030c5b5772abadabd3f4a11fb1e443ffe80599..d02f916d8e59a914d2441fa2b81af9ac31dfbf86
        #define DMAR_ECEO_REG           0x408
        #define DMAR_ECRSP_REG          0x410
        #define DMAR_ECCAP_REG          0x430
----- --#define DMAR_VCCAP_REG          0xe30 /* Virtual command capability register */
----- --#define DMAR_VCMD_REG           0xe00 /* Virtual command register */
----- --#define DMAR_VCRSP_REG          0xe10 /* Virtual command response register */
        
        #define DMAR_IQER_REG_IQEI(reg)         FIELD_GET(GENMASK_ULL(3, 0), reg)
        #define DMAR_IQER_REG_ITESID(reg)       FIELD_GET(GENMASK_ULL(47, 32), reg)
@@@@@@@@@ -602,9 -602,6 -602,6 -602,6 -602,6 -599,6 -602,6 -602,9 +599,9 @@@@@@@@@ struct dmar_domain 
                                                 */
                u8 dirty_tracking:1;            /* Dirty tracking is enabled */
                u8 nested_parent:1;             /* Has other domains nested on it */
 ++++++         u8 has_mappings:1;              /* Has mappings configured through
 ++++++                                          * iommu_map() interface.
 ++++++                                          */
        
                spinlock_t lock;                /* Protect device tracking lists */
                struct list_head devices;       /* all devices' list */
@@@@@@@@@ -854,6 -851,6 -851,6 -851,6 -851,6 -848,181 -851,6 -854,6 +851,181 @@@@@@@@@ static inline bool context_present(stru
                return (context->lo & 1);
        }
        
+++++ ++#define LEVEL_STRIDE            (9)
+++++ ++#define LEVEL_MASK              (((u64)1 << LEVEL_STRIDE) - 1)
+++++ ++#define MAX_AGAW_WIDTH          (64)
+++++ ++#define MAX_AGAW_PFN_WIDTH      (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
+++++ ++
+++++ ++static inline int agaw_to_level(int agaw)
+++++ ++{
+++++ ++        return agaw + 2;
+++++ ++}
+++++ ++
+++++ ++static inline int agaw_to_width(int agaw)
+++++ ++{
+++++ ++        return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH);
+++++ ++}
+++++ ++
+++++ ++static inline int width_to_agaw(int width)
+++++ ++{
+++++ ++        return DIV_ROUND_UP(width - 30, LEVEL_STRIDE);
+++++ ++}
+++++ ++
+++++ ++static inline unsigned int level_to_offset_bits(int level)
+++++ ++{
+++++ ++        return (level - 1) * LEVEL_STRIDE;
+++++ ++}
+++++ ++
+++++ ++static inline int pfn_level_offset(u64 pfn, int level)
+++++ ++{
+++++ ++        return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
+++++ ++}
+++++ ++
+++++ ++static inline u64 level_mask(int level)
+++++ ++{
+++++ ++        return -1ULL << level_to_offset_bits(level);
+++++ ++}
+++++ ++
+++++ ++static inline u64 level_size(int level)
+++++ ++{
+++++ ++        return 1ULL << level_to_offset_bits(level);
+++++ ++}
+++++ ++
+++++ ++static inline u64 align_to_level(u64 pfn, int level)
+++++ ++{
+++++ ++        return (pfn + level_size(level) - 1) & level_mask(level);
+++++ ++}
+++++ ++
+++++ ++static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
+++++ ++{
+++++ ++        return 1UL << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
+++++ ++}
+++++ ++
+++++ ++/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
+++++ ++   are never going to work. */
+++++ ++static inline unsigned long mm_to_dma_pfn_start(unsigned long mm_pfn)
+++++ ++{
+++++ ++        return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT);
+++++ ++}
+++++ ++static inline unsigned long mm_to_dma_pfn_end(unsigned long mm_pfn)
+++++ ++{
+++++ ++        return ((mm_pfn + 1) << (PAGE_SHIFT - VTD_PAGE_SHIFT)) - 1;
+++++ ++}
+++++ ++static inline unsigned long page_to_dma_pfn(struct page *pg)
+++++ ++{
+++++ ++        return mm_to_dma_pfn_start(page_to_pfn(pg));
+++++ ++}
+++++ ++static inline unsigned long virt_to_dma_pfn(void *p)
+++++ ++{
+++++ ++        return page_to_dma_pfn(virt_to_page(p));
+++++ ++}
+++++ ++
+++++ ++static inline void context_set_present(struct context_entry *context)
+++++ ++{
+++++ ++        context->lo |= 1;
+++++ ++}
+++++ ++
+++++ ++static inline void context_set_fault_enable(struct context_entry *context)
+++++ ++{
+++++ ++        context->lo &= (((u64)-1) << 2) | 1;
+++++ ++}
+++++ ++
+++++ ++static inline void context_set_translation_type(struct context_entry *context,
+++++ ++                                                unsigned long value)
+++++ ++{
+++++ ++        context->lo &= (((u64)-1) << 4) | 3;
+++++ ++        context->lo |= (value & 3) << 2;
+++++ ++}
+++++ ++
+++++ ++static inline void context_set_address_root(struct context_entry *context,
+++++ ++                                            unsigned long value)
+++++ ++{
+++++ ++        context->lo &= ~VTD_PAGE_MASK;
+++++ ++        context->lo |= value & VTD_PAGE_MASK;
+++++ ++}
+++++ ++
+++++ ++static inline void context_set_address_width(struct context_entry *context,
+++++ ++                                             unsigned long value)
+++++ ++{
+++++ ++        context->hi |= value & 7;
+++++ ++}
+++++ ++
+++++ ++static inline void context_set_domain_id(struct context_entry *context,
+++++ ++                                         unsigned long value)
+++++ ++{
+++++ ++        context->hi |= (value & ((1 << 16) - 1)) << 8;
+++++ ++}
+++++ ++
+++++ ++static inline void context_set_pasid(struct context_entry *context)
+++++ ++{
+++++ ++        context->lo |= CONTEXT_PASIDE;
+++++ ++}
+++++ ++
+++++ ++static inline int context_domain_id(struct context_entry *c)
+++++ ++{
+++++ ++        return((c->hi >> 8) & 0xffff);
+++++ ++}
+++++ ++
+++++ ++static inline void context_clear_entry(struct context_entry *context)
+++++ ++{
+++++ ++        context->lo = 0;
+++++ ++        context->hi = 0;
+++++ ++}
+++++ ++
+++++ ++#ifdef CONFIG_INTEL_IOMMU
+++++ ++static inline bool context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
+++++ ++{
+++++ ++        if (!iommu->copied_tables)
+++++ ++                return false;
+++++ ++
+++++ ++        return test_bit(((long)bus << 8) | devfn, iommu->copied_tables);
+++++ ++}
+++++ ++
+++++ ++static inline void
+++++ ++set_context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
+++++ ++{
+++++ ++        set_bit(((long)bus << 8) | devfn, iommu->copied_tables);
+++++ ++}
+++++ ++
+++++ ++static inline void
+++++ ++clear_context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
+++++ ++{
+++++ ++        clear_bit(((long)bus << 8) | devfn, iommu->copied_tables);
+++++ ++}
+++++ ++#endif /* CONFIG_INTEL_IOMMU */
+++++ ++
+++++ ++/*
+++++ ++ * Set the RID_PASID field of a scalable mode context entry. The
+++++ ++ * IOMMU hardware will use the PASID value set in this field for
+++++ ++ * DMA translations of DMA requests without PASID.
+++++ ++ */
+++++ ++static inline void
+++++ ++context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasid)
+++++ ++{
+++++ ++        context->hi |= pasid & ((1 << 20) - 1);
+++++ ++}
+++++ ++
+++++ ++/*
+++++ ++ * Set the DTE(Device-TLB Enable) field of a scalable mode context
+++++ ++ * entry.
+++++ ++ */
+++++ ++static inline void context_set_sm_dte(struct context_entry *context)
+++++ ++{
+++++ ++        context->lo |= BIT_ULL(2);
+++++ ++}
+++++ ++
+++++ ++/*
+++++ ++ * Set the PRE(Page Request Enable) field of a scalable mode context
+++++ ++ * entry.
+++++ ++ */
+++++ ++static inline void context_set_sm_pre(struct context_entry *context)
+++++ ++{
+++++ ++        context->lo |= BIT_ULL(4);
+++++ ++}
+++++ ++
+++++ ++/* Convert value to context PASID directory size field coding. */
+++++ ++#define context_pdts(pds)       (((pds) & 0x7) << 9)
+++++ ++
        struct dmar_drhd_unit *dmar_find_matched_drhd_unit(struct pci_dev *dev);
        
        int dmar_enable_qi(struct intel_iommu *iommu);
@@@@@@@@@ -900,7 -897,7 -897,7 -897,7 -897,7 -1069,6 -897,7 -900,7 +1072,6 @@@@@@@@@ int dmar_ir_support(void)
        void *alloc_pgtable_page(int node, gfp_t gfp);
        void free_pgtable_page(void *vaddr);
        void iommu_flush_write_buffer(struct intel_iommu *iommu);
----- --struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn);
        struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
                                                       const struct iommu_user_data *user_data);
        
index ac12f76c1212ac5f8f3a835f9afc1a0f6737af14,50a481c895b867202a4317afb7ef19a5666eafe5,50a481c895b867202a4317afb7ef19a5666eafe5,50a481c895b867202a4317afb7ef19a5666eafe5,50a481c895b867202a4317afb7ef19a5666eafe5,cc138e3ed4a6b64d2c30931f94b857c831164397,50a481c895b867202a4317afb7ef19a5666eafe5,4dbfa970dab53dfe97420a7a86c6f129deafe08a..40edd282903fbe7c804512819aa95c3a1ae9d43e
@@@@@@@@@ -216,27 -216,6 -216,6 -216,6 -216,6 -216,6 -216,6 -216,27 +216,27 @@@@@@@@@ static void intel_flush_svm_range(struc
                rcu_read_unlock();
        }
        
 ++++++ static void intel_flush_svm_all(struct intel_svm *svm)
 ++++++ {
 ++++++         struct device_domain_info *info;
 ++++++         struct intel_svm_dev *sdev;
 ++++++ 
 ++++++         rcu_read_lock();
 ++++++         list_for_each_entry_rcu(sdev, &svm->devs, list) {
 ++++++                 info = dev_iommu_priv_get(sdev->dev);
 ++++++ 
 ++++++                 qi_flush_piotlb(sdev->iommu, sdev->did, svm->pasid, 0, -1UL, 0);
 ++++++                 if (info->ats_enabled) {
 ++++++                         qi_flush_dev_iotlb_pasid(sdev->iommu, sdev->sid, info->pfsid,
 ++++++                                                  svm->pasid, sdev->qdep,
 ++++++                                                  0, 64 - VTD_PAGE_SHIFT);
 ++++++                         quirk_extra_dev_tlb_flush(info, 0, 64 - VTD_PAGE_SHIFT,
 ++++++                                                   svm->pasid, sdev->qdep);
 ++++++                 }
 ++++++         }
 ++++++         rcu_read_unlock();
 ++++++ }
 ++++++ 
        /* Pages have been freed at this point */
        static void intel_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn,
                                                struct mm_struct *mm,
        {
                struct intel_svm *svm = container_of(mn, struct intel_svm, notifier);
        
 ++++++         if (start == 0 && end == -1UL) {
 ++++++                 intel_flush_svm_all(svm);
 ++++++                 return;
 ++++++         }
 ++++++ 
                intel_flush_svm_range(svm, start,
                                      (end - start + PAGE_SIZE - 1) >> VTD_PAGE_SHIFT, 0);
        }
        }
        
        static int intel_svm_bind_mm(struct intel_iommu *iommu, struct device *dev,
-------                              struct mm_struct *mm)
+++++++                              struct iommu_domain *domain, ioasid_t pasid)
        {
                struct device_domain_info *info = dev_iommu_priv_get(dev);
+++++++         struct mm_struct *mm = domain->mm;
                struct intel_svm_dev *sdev;
                struct intel_svm *svm;
                unsigned long sflags;
                int ret = 0;
        
-------         svm = pasid_private_find(mm->pasid);
+++++++         svm = pasid_private_find(pasid);
                if (!svm) {
                        svm = kzalloc(sizeof(*svm), GFP_KERNEL);
                        if (!svm)
                                return -ENOMEM;
        
-------                 svm->pasid = mm->pasid;
+++++++                 svm->pasid = pasid;
                        svm->mm = mm;
                        INIT_LIST_HEAD_RCU(&svm->devs);
        
        
                /* Setup the pasid table: */
                sflags = cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0;
-------         ret = intel_pasid_setup_first_level(iommu, dev, mm->pgd, mm->pasid,
+++++++         ret = intel_pasid_setup_first_level(iommu, dev, mm->pgd, pasid,
                                                    FLPT_DEFAULT_DID, sflags);
                if (ret)
                        goto free_sdev;
@@@@@@@@@ -382,7 -356,7 -356,7 -356,7 -356,7 -356,7 -356,7 -383,7 +383,7 @@@@@@@@@ free_sdev
        free_svm:
                if (list_empty(&svm->devs)) {
                        mmu_notifier_unregister(&svm->notifier, mm);
-------                 pasid_private_remove(mm->pasid);
+++++++                 pasid_private_remove(pasid);
                        kfree(svm);
                }
        
        void intel_svm_remove_dev_pasid(struct device *dev, u32 pasid)
        {
                struct intel_svm_dev *sdev;
----- --        struct intel_iommu *iommu;
                struct intel_svm *svm;
                struct mm_struct *mm;
        
----- --        iommu = device_to_iommu(dev, NULL, NULL);
----- --        if (!iommu)
----- --                return;
----- --
                if (pasid_to_svm_sdev(dev, pasid, &svm, &sdev))
                        return;
                mm = svm->mm;
@@@@@@@@@ -750,25 -724,25 -724,25 -724,25 -724,25 -719,16 -724,25 -751,25 +746,16 @@@@@@@@@ int intel_svm_page_response(struct devi
                                    struct iommu_fault_event *evt,
                                    struct iommu_page_response *msg)
        {
+++++ ++        struct device_domain_info *info = dev_iommu_priv_get(dev);
+++++ ++        struct intel_iommu *iommu = info->iommu;
+++++ ++        u8 bus = info->bus, devfn = info->devfn;
                struct iommu_fault_page_request *prm;
----- --        struct intel_iommu *iommu;
                bool private_present;
                bool pasid_present;
                bool last_page;
----- --        u8 bus, devfn;
                int ret = 0;
                u16 sid;
        
----- --        if (!dev || !dev_is_pci(dev))
----- --                return -ENODEV;
----- --
----- --        iommu = device_to_iommu(dev, &bus, &devfn);
----- --        if (!iommu)
----- --                return -ENODEV;
----- --
----- --        if (!msg || !evt)
----- --                return -EINVAL;
----- --
                prm = &evt->fault.prm;
                sid = PCI_DEVID(bus, devfn);
                pasid_present = prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
@@@@@@@@@ -822,9 -796,9 -796,9 -796,9 -796,9 -782,9 -796,9 -823,8 +809,8 @@@@@@@@@ static int intel_svm_set_dev_pasid(stru
        {
                struct device_domain_info *info = dev_iommu_priv_get(dev);
                struct intel_iommu *iommu = info->iommu;
-------         struct mm_struct *mm = domain->mm;
        
-------         return intel_svm_bind_mm(iommu, dev, mm);
+++++++         return intel_svm_bind_mm(iommu, dev, domain, pasid);
        }
        
        static void intel_svm_domain_free(struct iommu_domain *domain)
index cbb5df0a6c32f835b50535a84bde3f44bfb4d6db,2abbeafdbd22d86019f665662f30fb367c40bd2e,2abbeafdbd22d86019f665662f30fb367c40bd2e,2abbeafdbd22d86019f665662f30fb367c40bd2e,2abbeafdbd22d86019f665662f30fb367c40bd2e,2abbeafdbd22d86019f665662f30fb367c40bd2e,2abbeafdbd22d86019f665662f30fb367c40bd2e,5be7f513b622d4c4eabecad230873a880ae9a4ca..29612106a962acd2609e6c8cf2bb04a0dbd8ae4b
@@@@@@@@@ -135,6 -135,6 -135,6 -135,6 -135,6 -135,6 -135,6 -135,7 +135,7 @@@@@@@@@ iommufd_hwpt_paging_alloc(struct iommuf
                                hwpt->domain = NULL;
                                goto out_abort;
                        }
+++++++                 hwpt->domain->owner = ops;
                } else {
                        hwpt->domain = iommu_domain_alloc(idev->dev->bus);
                        if (!hwpt->domain) {
@@@@@@@@@ -233,6 -233,6 -233,6 -233,6 -233,6 -233,6 -233,6 -234,7 +234,7 @@@@@@@@@ iommufd_hwpt_nested_alloc(struct iommuf
                        hwpt->domain = NULL;
                        goto out_abort;
                }
+++++++         hwpt->domain->owner = ops;
        
                if (WARN_ON_ONCE(hwpt->domain->type != IOMMU_DOMAIN_NESTED)) {
                        rc = -EINVAL;
@@@@@@@@@ -318,9 -318,9 -318,9 -318,9 -318,9 -318,9 -318,9 -320,9 +320,9 @@@@@@@@@ out_unlock
                if (ioas)
                        mutex_unlock(&ioas->mutex);
        out_put_pt:
 -------        iommufd_put_object(pt_obj);
 +++++++        iommufd_put_object(ucmd->ictx, pt_obj);
        out_put_idev:
 -------        iommufd_put_object(&idev->obj);
 +++++++        iommufd_put_object(ucmd->ictx, &idev->obj);
                return rc;
        }
        
@@@@@@@@@ -345,7 -345,7 -345,7 -345,7 -345,7 -345,7 -345,7 -347,7 +347,7 @@@@@@@@@ int iommufd_hwpt_set_dirty_tracking(str
                rc = iopt_set_dirty_tracking(&ioas->iopt, hwpt_paging->common.domain,
                                             enable);
        
 -------        iommufd_put_object(&hwpt_paging->common.obj);
 +++++++        iommufd_put_object(ucmd->ictx, &hwpt_paging->common.obj);
                return rc;
        }
        
@@@@@@@@@ -368,6 -368,6 -368,6 -368,6 -368,6 -368,6 -368,6 -370,6 +370,6 @@@@@@@@@ int iommufd_hwpt_get_dirty_bitmap(struc
                rc = iopt_read_and_clear_dirty_data(
                        &ioas->iopt, hwpt_paging->common.domain, cmd->flags, cmd);
        
 -------        iommufd_put_object(&hwpt_paging->common.obj);
 +++++++        iommufd_put_object(ucmd->ictx, &hwpt_paging->common.obj);
                return rc;
        }
diff --combined drivers/iommu/of_iommu.c
index 35ba090f3b5e24e615e7a604f18fb0d532706a6a,157b286e36bf3a1ee1b312138c761d6e8dc97911,157b286e36bf3a1ee1b312138c761d6e8dc97911,157b286e36bf3a1ee1b312138c761d6e8dc97911,157b286e36bf3a1ee1b312138c761d6e8dc97911,157b286e36bf3a1ee1b312138c761d6e8dc97911,157b286e36bf3a1ee1b312138c761d6e8dc97911,691335a903a89913235cd91467daa52001bee1f7..719652b608407ad905721d676ff7a0c245e76ee0
        #include <linux/slab.h>
        #include <linux/fsl/mc.h>
        
------- #define NO_IOMMU        1
------- 
        static int of_iommu_xlate(struct device *dev,
                                  struct of_phandle_args *iommu_spec)
        {
                ops = iommu_ops_from_fwnode(fwnode);
                if ((ops && !ops->of_xlate) ||
                    !of_device_is_available(iommu_spec->np))
-------                 return NO_IOMMU;
+++++++                 return -ENODEV;
        
                ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
                if (ret)
@@@@@@@@@ -61,7 -61,7 -61,7 -61,7 -61,7 -61,7 -61,7 -59,7 +59,7 @@@@@@@@@ static int of_iommu_configure_dev_id(st
                                 "iommu-map-mask", &iommu_spec.np,
                                 iommu_spec.args);
                if (err)
-------                 return err == -ENODEV ? NO_IOMMU : err;
+++++++                 return err;
        
                err = of_iommu_xlate(dev, &iommu_spec);
                of_node_put(iommu_spec.np);
@@@@@@@@@ -72,7 -72,7 -72,7 -72,7 -72,7 -72,7 -72,7 -70,7 +70,7 @@@@@@@@@ static int of_iommu_configure_dev(struc
                                          struct device *dev)
        {
                struct of_phandle_args iommu_spec;
-------         int err = NO_IOMMU, idx = 0;
+++++++         int err = -ENODEV, idx = 0;
        
                while (!of_parse_phandle_with_args(master_np, "iommus",
                                                   "#iommu-cells",
@@@@@@@@@ -107,25 -107,21 -107,21 -107,21 -107,21 -107,21 -107,21 -105,30 +105,30 @@@@@@@@@ static int of_iommu_configure_device(st
                              of_iommu_configure_dev(master_np, dev);
        }
        
------- const struct iommu_ops *of_iommu_configure(struct device *dev,
-------                                            struct device_node *master_np,
-------                                            const u32 *id)
+++++++ /*
+++++++  * Returns:
+++++++  *  0 on success, an iommu was configured
+++++++  *  -ENODEV if the device does not have any IOMMU
+++++++  *  -EPROBEDEFER if probing should be tried again
+++++++  *  -errno fatal errors
+++++++  */
+++++++ int of_iommu_configure(struct device *dev, struct device_node *master_np,
+++++++                        const u32 *id)
        {
-------         const struct iommu_ops *ops = NULL;
 ------         struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 ------         int err = NO_IOMMU;
 ++++++         struct iommu_fwspec *fwspec;
-               int err = NO_IOMMU;
+++++++         int err;
        
                if (!master_np)
-------                 return NULL;
+++++++                 return -ENODEV;
        
 ++++++         /* Serialise to make dev->iommu stable under our potential fwspec */
 ++++++         mutex_lock(&iommu_probe_device_lock);
 ++++++         fwspec = dev_iommu_fwspec_get(dev);
                if (fwspec) {
 ------                 if (fwspec->ops)
 ------                         return fwspec->ops;
 ------ 
 ++++++                 if (fwspec->ops) {
 ++++++                         mutex_unlock(&iommu_probe_device_lock);
-                               return fwspec->ops;
+++++++                         return 0;
 ++++++                 }
                        /* In the deferred case, start again from scratch */
                        iommu_fwspec_free(dev);
                }
                } else {
                        err = of_iommu_configure_device(master_np, dev, id);
                }
-       
-               /*
-                * Two success conditions can be represented by non-negative err here:
-                * >0 : there is no IOMMU, or one was unavailable for non-fatal reasons
-                *  0 : we found an IOMMU, and dev->fwspec is initialised appropriately
-                * <0 : any actual error
-                */
-               if (!err) {
-                       /* The fwspec pointer changed, read it again */
-                       fwspec = dev_iommu_fwspec_get(dev);
-                       ops    = fwspec->ops;
-               }
 ++++++         mutex_unlock(&iommu_probe_device_lock);
        
 ------         /*
 ------          * Two success conditions can be represented by non-negative err here:
 ------          * >0 : there is no IOMMU, or one was unavailable for non-fatal reasons
 ------          *  0 : we found an IOMMU, and dev->fwspec is initialised appropriately
 ------          * <0 : any actual error
 ------          */
 ------         if (!err) {
 ------                 /* The fwspec pointer changed, read it again */
 ------                 fwspec = dev_iommu_fwspec_get(dev);
 ------                 ops    = fwspec->ops;
 ------         }
-------         /*
-------          * If we have reason to believe the IOMMU driver missed the initial
-------          * probe for dev, replay it to get things in order.
-------          */
-------         if (!err && dev->bus)
-------                 err = iommu_probe_device(dev);
------- 
-------         /* Ignore all other errors apart from EPROBE_DEFER */
-------         if (err == -EPROBE_DEFER) {
-------                 ops = ERR_PTR(err);
-------         } else if (err < 0) {
-------                 dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-------                 ops = NULL;
-------         }
+++++++         if (err == -ENODEV || err == -EPROBE_DEFER)
+++++++                 return err;
+++++++         if (err)
+++++++                 goto err_log;
        
-------         return ops;
+++++++         err = iommu_probe_device(dev);
+++++++         if (err)
+++++++                 goto err_log;
+++++++         return 0;
+++++++ 
+++++++ err_log:
+++++++         dev_dbg(dev, "Adding to IOMMU failed: %pe\n", ERR_PTR(err));
+++++++         return err;
        }
        
        static enum iommu_resv_type __maybe_unused
@@@@@@@@@ -197,7 -191,7 -191,7 -191,7 -191,7 -191,7 -191,7 -185,7 +185,7 @@@@@@@@@ iommu_resv_region_get_type(struct devic
                if (start == phys->start && end == phys->end)
                        return IOMMU_RESV_DIRECT;
        
 -------        dev_warn(dev, "treating non-direct mapping [%pr] -> [%pap-%pap] as reservation\n", &phys,
 +++++++        dev_warn(dev, "treating non-direct mapping [%pr] -> [%pap-%pap] as reservation\n", phys,
                         &start, &end);
                return IOMMU_RESV_RESERVED;
        }
@@@@@@@@@ -260,7 -254,7 -254,7 -254,7 -254,7 -254,7 -254,7 -248,14 +248,14 @@@@@@@@@ void of_iommu_get_resv_regions(struct d
                                        phys_addr_t iova;
                                        size_t length;
        
+++++++                                 if (of_dma_is_coherent(dev->of_node))
+++++++                                         prot |= IOMMU_CACHE;
+++++++ 
                                        maps = of_translate_dma_region(np, maps, &iova, &length);
+++++++                                 if (length == 0) {
+++++++                                         dev_warn(dev, "Cannot reserve IOVA region of 0 size\n");
+++++++                                         continue;
+++++++                                 }
                                        type = iommu_resv_region_get_type(dev, &phys, iova, length);
        
                                        region = iommu_alloc_resv_region(iova, length, prot, type,
index 379ebe03efb6d45b42afd8a63b4fcb830bb37903,379ebe03efb6d45b42afd8a63b4fcb830bb37903,379ebe03efb6d45b42afd8a63b4fcb830bb37903,379ebe03efb6d45b42afd8a63b4fcb830bb37903,ef6a87445105946ac79d0ec2aa9378792bc4860a,379ebe03efb6d45b42afd8a63b4fcb830bb37903,379ebe03efb6d45b42afd8a63b4fcb830bb37903,9bcffdde6175d3fd2117cea334eb14abe3a8fa8e..34db37fd9675cd98403633547b34663c2241821d
@@@@@@@@@ -843,7 -843,7 -843,7 -843,7 -843,7 -843,7 -843,7 -843,7 +843,7 @@@@@@@@@ static int viommu_map_pages(struct iomm
                                .flags          = cpu_to_le32(flags),
                        };
        
---- ---                ret = viommu_send_req_sync(vdomain->viommu, &map, sizeof(map));
++++ +++                ret = viommu_add_req(vdomain->viommu, &map, sizeof(map));
                        if (ret) {
                                viommu_del_mappings(vdomain, iova, end);
                                return ret;
@@@@@@@@@ -912,6 -912,6 -912,6 -912,6 -912,33 -912,6 -912,6 -912,6 +912,33 @@@@@@@@@ static void viommu_iotlb_sync(struct io
                viommu_sync_req(vdomain->viommu);
        }
        
++++ +++static int viommu_iotlb_sync_map(struct iommu_domain *domain,
++++ +++                                 unsigned long iova, size_t size)
++++ +++{
++++ +++        struct viommu_domain *vdomain = to_viommu_domain(domain);
++++ +++
++++ +++        /*
++++ +++         * May be called before the viommu is initialized including
++++ +++         * while creating direct mapping
++++ +++         */
++++ +++        if (!vdomain->nr_endpoints)
++++ +++                return 0;
++++ +++        return viommu_sync_req(vdomain->viommu);
++++ +++}
++++ +++
++++ +++static void viommu_flush_iotlb_all(struct iommu_domain *domain)
++++ +++{
++++ +++        struct viommu_domain *vdomain = to_viommu_domain(domain);
++++ +++
++++ +++        /*
++++ +++         * May be called before the viommu is initialized including
++++ +++         * while creating direct mapping
++++ +++         */
++++ +++        if (!vdomain->nr_endpoints)
++++ +++                return;
++++ +++        viommu_sync_req(vdomain->viommu);
++++ +++}
++++ +++
        static void viommu_get_resv_regions(struct device *dev, struct list_head *head)
        {
                struct iommu_resv_region *entry, *new_entry, *msi = NULL;
@@@@@@@@@ -969,9 -969,9 -969,9 -969,9 -996,9 -969,9 -969,9 -969,6 +996,6 @@@@@@@@@ static struct iommu_device *viommu_prob
                struct viommu_dev *viommu = NULL;
                struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
        
-------         if (!fwspec || fwspec->ops != &viommu_ops)
-------                 return ERR_PTR(-ENODEV);
------- 
                viommu = viommu_get_by_fwnode(fwspec->iommu_fwnode);
                if (!viommu)
                        return ERR_PTR(-ENODEV);
@@@@@@@@@ -1037,6 -1037,6 -1037,6 -1037,6 -1064,8 -1037,6 -1037,6 -1034,6 +1061,8 @@@@@@@@@ static bool viommu_capable(struct devic
                switch (cap) {
                case IOMMU_CAP_CACHE_COHERENCY:
                        return true;
++++ +++        case IOMMU_CAP_DEFERRED_FLUSH:
++++ +++                return true;
                default:
                        return false;
                }
@@@@@@@@@ -1057,7 -1057,7 -1057,7 -1057,7 -1086,9 -1057,7 -1057,7 -1054,7 +1083,9 @@@@@@@@@ static struct iommu_ops viommu_ops = 
                        .map_pages              = viommu_map_pages,
                        .unmap_pages            = viommu_unmap_pages,
                        .iova_to_phys           = viommu_iova_to_phys,
++++ +++                .flush_iotlb_all        = viommu_flush_iotlb_all,
                        .iotlb_sync             = viommu_iotlb_sync,
++++ +++                .iotlb_sync_map         = viommu_iotlb_sync_map,
                        .free                   = viommu_domain_free,
                }
        };
diff --combined include/linux/device.h
index 6c83294395ac08a0aa4a61f5de74c225b29624e6,d7a72a8749ea03e413868a87470b3e8df074c737,d7a72a8749ea03e413868a87470b3e8df074c737,d7a72a8749ea03e413868a87470b3e8df074c737,d7a72a8749ea03e413868a87470b3e8df074c737,d7a72a8749ea03e413868a87470b3e8df074c737,d7a72a8749ea03e413868a87470b3e8df074c737,0314dbbdb5345f66ae6f903dbc7aafb259beb52f..bd05b2c35e99bec20dee0e118daf3d084adfdab9
@@@@@@@@@ -42,7 -42,7 -42,7 -42,7 -42,7 -42,7 -42,7 -42,6 +42,6 @@@@@@@@@ struct class
        struct subsys_private;
        struct device_node;
        struct fwnode_handle;
------- struct iommu_ops;
        struct iommu_group;
        struct dev_pin_info;
        struct dev_iommu;
@@@@@@@@@ -1006,8 -1006,6 -1006,6 -1006,6 -1006,6 -1006,6 -1006,6 -1005,6 +1005,8 @@@@@@@@@ static inline void device_unlock(struc
        {
                mutex_unlock(&dev->mutex);
        }
 +++++++
 +++++++DEFINE_GUARD(device, struct device *, device_lock(_T), device_unlock(_T))
        
        static inline void device_lock_assert(struct device *dev)
        {
diff --combined mm/Kconfig
index 57cd378c73d67fb369d39cfbb90259246531a274,89971a894b6058fd7b908c0e8ffa216cbdc887dd,89971a894b6058fd7b908c0e8ffa216cbdc887dd,89971a894b6058fd7b908c0e8ffa216cbdc887dd,89971a894b6058fd7b908c0e8ffa216cbdc887dd,89971a894b6058fd7b908c0e8ffa216cbdc887dd,89971a894b6058fd7b908c0e8ffa216cbdc887dd,0143f4d905c9656c627537ec7755fe170cf9337b..0a80a168d4aedec63c959e4a1ae0b8769d2941d2
@@@@@@@@@ -1201,6 -1201,13 -1201,13 -1201,13 -1201,13 -1201,13 -1201,13 -1201,13 +1201,6 @@@@@@@@@ config ANON_VMA_NAM
                  area from being merged with adjacent virtual memory areas due to the
                  difference in their name.
        
 -------config USERFAULTFD
 -------        bool "Enable userfaultfd() system call"
 -------        depends on MMU
 -------        help
 -------          Enable the userfaultfd() system call that allows to intercept and
 -------          handle page faults in userland.
 -------
        config HAVE_ARCH_USERFAULTFD_WP
                bool
                help
@@@@@@@@@ -1211,14 -1218,6 -1218,6 -1218,6 -1218,6 -1218,6 -1218,6 -1218,6 +1211,14 @@@@@@@@@ config HAVE_ARCH_USERFAULTFD_MINO
                help
                  Arch has userfaultfd minor fault support
        
 +++++++menuconfig USERFAULTFD
 +++++++        bool "Enable userfaultfd() system call"
 +++++++        depends on MMU
 +++++++        help
 +++++++          Enable the userfaultfd() system call that allows to intercept and
 +++++++          handle page faults in userland.
 +++++++
 +++++++if USERFAULTFD
        config PTE_MARKER_UFFD_WP
                bool "Userfaultfd write protection support for shmem/hugetlbfs"
                default y
                  Allows to create marker PTEs for userfaultfd write protection
                  purposes.  It is required to enable userfaultfd write protection on
                  file-backed memory types like shmem and hugetlbfs.
 +++++++endif # USERFAULTFD
        
        # multi-gen LRU {
        config LRU_GEN
@@@@@@@@@ -1272,6 -1270,6 -1270,6 -1270,6 -1270,6 -1270,6 -1270,6 -1270,9 +1272,9 @@@@@@@@@ config LOCK_MM_AND_FIND_VM
                bool
                depends on !STACK_GROWSUP
        
+++++++ config IOMMU_MM_DATA
+++++++         bool
+++++++ 
        source "mm/damon/Kconfig"
        
        endmenu
This page took 0.238801 seconds and 4 git commands to generate.