Loading Documentation/arch/arm64/silicon-errata.rst +7 −1 Original line number Diff line number Diff line Loading @@ -207,8 +207,14 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-600 | #1076982,1209401| N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-700 | #2268618,2812531| N/A | | ARM | MMU-700 | #2133013, | N/A | | | | #2268618, | | | | | #2812531, | | | | | #3777127 | | +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU L1 | #3878312 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU S3 | #3995052 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | GIC-700 | #2941627 | ARM64_ERRATUM_2941627 | +----------------+-----------------+-----------------+-----------------------------+ Loading Documentation/devicetree/bindings/iommu/arm,smmu.yaml +2 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ properties: - description: Qcom SoCs implementing "qcom,smmu-500" and "arm,mmu-500" items: - enum: - qcom,eliza-smmu-500 - qcom,glymur-smmu-500 - qcom,kaanapali-smmu-500 - qcom,milos-smmu-500 Loading Loading @@ -92,6 +93,7 @@ properties: items: - enum: - qcom,glymur-smmu-500 - qcom,hawi-smmu-500 - qcom,kaanapali-smmu-500 - qcom,milos-smmu-500 - qcom,qcm2290-smmu-500 Loading drivers/iommu/amd/debugfs.c +31 −32 Original line number Diff line number Diff line Loading @@ -26,22 +26,19 @@ static ssize_t iommu_mmio_write(struct file *filp, const char __user *ubuf, { struct seq_file *m = filp->private_data; struct amd_iommu *iommu = m->private; int ret; iommu->dbg_mmio_offset = -1; int ret, dbg_mmio_offset = iommu->dbg_mmio_offset = -1; if (cnt > OFS_IN_SZ) return -EINVAL; ret = kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_mmio_offset); ret = kstrtou32_from_user(ubuf, cnt, 0, &dbg_mmio_offset); if (ret) return ret; if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) { iommu->dbg_mmio_offset = -1; if (dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) return -EINVAL; } iommu->dbg_mmio_offset = dbg_mmio_offset; return cnt; } Loading @@ -49,14 +46,16 @@ static int iommu_mmio_show(struct seq_file *m, void *unused) { struct amd_iommu *iommu = m->private; u64 value; int dbg_mmio_offset = iommu->dbg_mmio_offset; if (iommu->dbg_mmio_offset < 0) { if (dbg_mmio_offset < 0 || dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) { seq_puts(m, "Please provide mmio register's offset\n"); return 0; } value = readq(iommu->mmio_base + iommu->dbg_mmio_offset); seq_printf(m, "Offset:0x%x Value:0x%016llx\n", iommu->dbg_mmio_offset, value); value = readq(iommu->mmio_base + dbg_mmio_offset); seq_printf(m, "Offset:0x%x Value:0x%016llx\n", dbg_mmio_offset, value); return 0; } Loading @@ -67,23 +66,20 @@ static ssize_t iommu_capability_write(struct file *filp, const char __user *ubuf { struct seq_file *m = filp->private_data; struct amd_iommu *iommu = m->private; int ret; iommu->dbg_cap_offset = -1; int ret, dbg_cap_offset = iommu->dbg_cap_offset = -1; if (cnt > OFS_IN_SZ) return -EINVAL; ret = kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_cap_offset); ret = kstrtou32_from_user(ubuf, cnt, 0, &dbg_cap_offset); if (ret) return ret; /* Capability register at offset 0x14 is the last IOMMU capability register. */ if (iommu->dbg_cap_offset > 0x14) { iommu->dbg_cap_offset = -1; if (dbg_cap_offset > 0x14) return -EINVAL; } iommu->dbg_cap_offset = dbg_cap_offset; return cnt; } Loading @@ -91,21 +87,21 @@ static int iommu_capability_show(struct seq_file *m, void *unused) { struct amd_iommu *iommu = m->private; u32 value; int err; int err, dbg_cap_offset = iommu->dbg_cap_offset; if (iommu->dbg_cap_offset < 0) { if (dbg_cap_offset < 0 || dbg_cap_offset > 0x14) { seq_puts(m, "Please provide capability register's offset in the range [0x00 - 0x14]\n"); return 0; } err = pci_read_config_dword(iommu->dev, iommu->cap_ptr + iommu->dbg_cap_offset, &value); err = pci_read_config_dword(iommu->dev, iommu->cap_ptr + dbg_cap_offset, &value); if (err) { seq_printf(m, "Not able to read capability register at 0x%x\n", iommu->dbg_cap_offset); dbg_cap_offset); return 0; } seq_printf(m, "Offset:0x%x Value:0x%08x\n", iommu->dbg_cap_offset, value); seq_printf(m, "Offset:0x%x Value:0x%08x\n", dbg_cap_offset, value); return 0; } Loading Loading @@ -197,10 +193,11 @@ static ssize_t devid_write(struct file *filp, const char __user *ubuf, static int devid_show(struct seq_file *m, void *unused) { u16 devid; int sbdf_shadow = sbdf; if (sbdf >= 0) { devid = PCI_SBDF_TO_DEVID(sbdf); seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf), if (sbdf_shadow >= 0) { devid = PCI_SBDF_TO_DEVID(sbdf_shadow); seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf_shadow), PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid)); } else seq_puts(m, "No or Invalid input provided\n"); Loading Loading @@ -237,13 +234,14 @@ static int iommu_devtbl_show(struct seq_file *m, void *unused) { struct amd_iommu_pci_seg *pci_seg; u16 seg, devid; int sbdf_shadow = sbdf; if (sbdf < 0) { if (sbdf_shadow < 0) { seq_puts(m, "Enter a valid device ID to 'devid' file\n"); return 0; } seg = PCI_SBDF_TO_SEGID(sbdf); devid = PCI_SBDF_TO_DEVID(sbdf); seg = PCI_SBDF_TO_SEGID(sbdf_shadow); devid = PCI_SBDF_TO_DEVID(sbdf_shadow); for_each_pci_segment(pci_seg) { if (pci_seg->id != seg) Loading Loading @@ -336,19 +334,20 @@ static int iommu_irqtbl_show(struct seq_file *m, void *unused) { struct amd_iommu_pci_seg *pci_seg; u16 devid, seg; int sbdf_shadow = sbdf; if (!irq_remapping_enabled) { seq_puts(m, "Interrupt remapping is disabled\n"); return 0; } if (sbdf < 0) { if (sbdf_shadow < 0) { seq_puts(m, "Enter a valid device ID to 'devid' file\n"); return 0; } seg = PCI_SBDF_TO_SEGID(sbdf); devid = PCI_SBDF_TO_DEVID(sbdf); seg = PCI_SBDF_TO_SEGID(sbdf_shadow); devid = PCI_SBDF_TO_DEVID(sbdf_shadow); for_each_pci_segment(pci_seg) { if (pci_seg->id != seg) Loading drivers/iommu/amd/init.c +6 −3 Original line number Diff line number Diff line Loading @@ -848,10 +848,11 @@ static void __init free_command_buffer(struct amd_iommu *iommu) void *__init iommu_alloc_4k_pages(struct amd_iommu *iommu, gfp_t gfp, size_t size) { int nid = iommu->dev ? dev_to_node(&iommu->dev->dev) : NUMA_NO_NODE; void *buf; size = PAGE_ALIGN(size); buf = iommu_alloc_pages_sz(gfp, size); buf = iommu_alloc_pages_node_sz(nid, gfp, size); if (!buf) return NULL; if (check_feature(FEATURE_SNP) && Loading Loading @@ -954,14 +955,16 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu) static int iommu_init_ga_log(struct amd_iommu *iommu) { int nid = iommu->dev ? dev_to_node(&iommu->dev->dev) : NUMA_NO_NODE; if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir)) return 0; iommu->ga_log = iommu_alloc_pages_sz(GFP_KERNEL, GA_LOG_SIZE); iommu->ga_log = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, GA_LOG_SIZE); if (!iommu->ga_log) goto err_out; iommu->ga_log_tail = iommu_alloc_pages_sz(GFP_KERNEL, 8); iommu->ga_log_tail = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, 8); if (!iommu->ga_log_tail) goto err_out; Loading drivers/iommu/amd/iommu.c +33 −10 Original line number Diff line number Diff line Loading @@ -403,11 +403,12 @@ struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid) return NULL; } static int clone_alias(struct pci_dev *pdev, u16 alias, void *data) static int clone_alias(struct pci_dev *pdev_origin, u16 alias, void *data) { struct dev_table_entry new; struct amd_iommu *iommu; struct iommu_dev_data *dev_data, *alias_data; struct pci_dev *pdev = data; u16 devid = pci_dev_id(pdev); int ret = 0; Loading Loading @@ -454,9 +455,9 @@ static void clone_aliases(struct amd_iommu *iommu, struct device *dev) * part of the PCI DMA aliases if it's bus differs * from the original device. */ clone_alias(pdev, iommu->pci_seg->alias_table[pci_dev_id(pdev)], NULL); clone_alias(pdev, iommu->pci_seg->alias_table[pci_dev_id(pdev)], pdev); pci_for_each_dma_alias(pdev, clone_alias, NULL); pci_for_each_dma_alias(pdev, clone_alias, pdev); } static void setup_aliases(struct amd_iommu *iommu, struct device *dev) Loading Loading @@ -2991,13 +2992,17 @@ static bool amd_iommu_capable(struct device *dev, enum iommu_cap cap) return amdr_ivrs_remap_support; case IOMMU_CAP_ENFORCE_CACHE_COHERENCY: return true; case IOMMU_CAP_DEFERRED_FLUSH: return true; case IOMMU_CAP_DIRTY_TRACKING: { struct amd_iommu *iommu = get_amd_iommu_from_dev(dev); return amd_iommu_hd_support(iommu); } case IOMMU_CAP_PCI_ATS_SUPPORTED: { struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev); return amd_iommu_iotlb_sup && (dev_data->flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP); } default: break; } Loading Loading @@ -3179,26 +3184,44 @@ const struct iommu_ops amd_iommu_ops = { static struct irq_chip amd_ir_chip; static DEFINE_SPINLOCK(iommu_table_lock); static int iommu_flush_dev_irt(struct pci_dev *unused, u16 devid, void *data) { int ret; struct iommu_cmd cmd; struct amd_iommu *iommu = data; build_inv_irt(&cmd, devid); ret = __iommu_queue_command_sync(iommu, &cmd, true); return ret; } static void iommu_flush_irt_and_complete(struct amd_iommu *iommu, u16 devid) { int ret; u64 data; unsigned long flags; struct iommu_cmd cmd, cmd2; struct iommu_cmd cmd; struct pci_dev *pdev = NULL; struct iommu_dev_data *dev_data = search_dev_data(iommu, devid); if (iommu->irtcachedis_enabled) return; build_inv_irt(&cmd, devid); if (dev_data && dev_data->dev && dev_is_pci(dev_data->dev)) pdev = to_pci_dev(dev_data->dev); raw_spin_lock_irqsave(&iommu->lock, flags); data = get_cmdsem_val(iommu); build_completion_wait(&cmd2, iommu, data); build_completion_wait(&cmd, iommu, data); ret = __iommu_queue_command_sync(iommu, &cmd, true); if (pdev) ret = pci_for_each_dma_alias(pdev, iommu_flush_dev_irt, iommu); else ret = iommu_flush_dev_irt(NULL, devid, iommu); if (ret) goto out_err; ret = __iommu_queue_command_sync(iommu, &cmd2, false); ret = __iommu_queue_command_sync(iommu, &cmd, false); if (ret) goto out_err; raw_spin_unlock_irqrestore(&iommu->lock, flags); Loading Loading
Documentation/arch/arm64/silicon-errata.rst +7 −1 Original line number Diff line number Diff line Loading @@ -207,8 +207,14 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-600 | #1076982,1209401| N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-700 | #2268618,2812531| N/A | | ARM | MMU-700 | #2133013, | N/A | | | | #2268618, | | | | | #2812531, | | | | | #3777127 | | +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU L1 | #3878312 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU S3 | #3995052 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | GIC-700 | #2941627 | ARM64_ERRATUM_2941627 | +----------------+-----------------+-----------------+-----------------------------+ Loading
Documentation/devicetree/bindings/iommu/arm,smmu.yaml +2 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ properties: - description: Qcom SoCs implementing "qcom,smmu-500" and "arm,mmu-500" items: - enum: - qcom,eliza-smmu-500 - qcom,glymur-smmu-500 - qcom,kaanapali-smmu-500 - qcom,milos-smmu-500 Loading Loading @@ -92,6 +93,7 @@ properties: items: - enum: - qcom,glymur-smmu-500 - qcom,hawi-smmu-500 - qcom,kaanapali-smmu-500 - qcom,milos-smmu-500 - qcom,qcm2290-smmu-500 Loading
drivers/iommu/amd/debugfs.c +31 −32 Original line number Diff line number Diff line Loading @@ -26,22 +26,19 @@ static ssize_t iommu_mmio_write(struct file *filp, const char __user *ubuf, { struct seq_file *m = filp->private_data; struct amd_iommu *iommu = m->private; int ret; iommu->dbg_mmio_offset = -1; int ret, dbg_mmio_offset = iommu->dbg_mmio_offset = -1; if (cnt > OFS_IN_SZ) return -EINVAL; ret = kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_mmio_offset); ret = kstrtou32_from_user(ubuf, cnt, 0, &dbg_mmio_offset); if (ret) return ret; if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) { iommu->dbg_mmio_offset = -1; if (dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) return -EINVAL; } iommu->dbg_mmio_offset = dbg_mmio_offset; return cnt; } Loading @@ -49,14 +46,16 @@ static int iommu_mmio_show(struct seq_file *m, void *unused) { struct amd_iommu *iommu = m->private; u64 value; int dbg_mmio_offset = iommu->dbg_mmio_offset; if (iommu->dbg_mmio_offset < 0) { if (dbg_mmio_offset < 0 || dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) { seq_puts(m, "Please provide mmio register's offset\n"); return 0; } value = readq(iommu->mmio_base + iommu->dbg_mmio_offset); seq_printf(m, "Offset:0x%x Value:0x%016llx\n", iommu->dbg_mmio_offset, value); value = readq(iommu->mmio_base + dbg_mmio_offset); seq_printf(m, "Offset:0x%x Value:0x%016llx\n", dbg_mmio_offset, value); return 0; } Loading @@ -67,23 +66,20 @@ static ssize_t iommu_capability_write(struct file *filp, const char __user *ubuf { struct seq_file *m = filp->private_data; struct amd_iommu *iommu = m->private; int ret; iommu->dbg_cap_offset = -1; int ret, dbg_cap_offset = iommu->dbg_cap_offset = -1; if (cnt > OFS_IN_SZ) return -EINVAL; ret = kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_cap_offset); ret = kstrtou32_from_user(ubuf, cnt, 0, &dbg_cap_offset); if (ret) return ret; /* Capability register at offset 0x14 is the last IOMMU capability register. */ if (iommu->dbg_cap_offset > 0x14) { iommu->dbg_cap_offset = -1; if (dbg_cap_offset > 0x14) return -EINVAL; } iommu->dbg_cap_offset = dbg_cap_offset; return cnt; } Loading @@ -91,21 +87,21 @@ static int iommu_capability_show(struct seq_file *m, void *unused) { struct amd_iommu *iommu = m->private; u32 value; int err; int err, dbg_cap_offset = iommu->dbg_cap_offset; if (iommu->dbg_cap_offset < 0) { if (dbg_cap_offset < 0 || dbg_cap_offset > 0x14) { seq_puts(m, "Please provide capability register's offset in the range [0x00 - 0x14]\n"); return 0; } err = pci_read_config_dword(iommu->dev, iommu->cap_ptr + iommu->dbg_cap_offset, &value); err = pci_read_config_dword(iommu->dev, iommu->cap_ptr + dbg_cap_offset, &value); if (err) { seq_printf(m, "Not able to read capability register at 0x%x\n", iommu->dbg_cap_offset); dbg_cap_offset); return 0; } seq_printf(m, "Offset:0x%x Value:0x%08x\n", iommu->dbg_cap_offset, value); seq_printf(m, "Offset:0x%x Value:0x%08x\n", dbg_cap_offset, value); return 0; } Loading Loading @@ -197,10 +193,11 @@ static ssize_t devid_write(struct file *filp, const char __user *ubuf, static int devid_show(struct seq_file *m, void *unused) { u16 devid; int sbdf_shadow = sbdf; if (sbdf >= 0) { devid = PCI_SBDF_TO_DEVID(sbdf); seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf), if (sbdf_shadow >= 0) { devid = PCI_SBDF_TO_DEVID(sbdf_shadow); seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf_shadow), PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid)); } else seq_puts(m, "No or Invalid input provided\n"); Loading Loading @@ -237,13 +234,14 @@ static int iommu_devtbl_show(struct seq_file *m, void *unused) { struct amd_iommu_pci_seg *pci_seg; u16 seg, devid; int sbdf_shadow = sbdf; if (sbdf < 0) { if (sbdf_shadow < 0) { seq_puts(m, "Enter a valid device ID to 'devid' file\n"); return 0; } seg = PCI_SBDF_TO_SEGID(sbdf); devid = PCI_SBDF_TO_DEVID(sbdf); seg = PCI_SBDF_TO_SEGID(sbdf_shadow); devid = PCI_SBDF_TO_DEVID(sbdf_shadow); for_each_pci_segment(pci_seg) { if (pci_seg->id != seg) Loading Loading @@ -336,19 +334,20 @@ static int iommu_irqtbl_show(struct seq_file *m, void *unused) { struct amd_iommu_pci_seg *pci_seg; u16 devid, seg; int sbdf_shadow = sbdf; if (!irq_remapping_enabled) { seq_puts(m, "Interrupt remapping is disabled\n"); return 0; } if (sbdf < 0) { if (sbdf_shadow < 0) { seq_puts(m, "Enter a valid device ID to 'devid' file\n"); return 0; } seg = PCI_SBDF_TO_SEGID(sbdf); devid = PCI_SBDF_TO_DEVID(sbdf); seg = PCI_SBDF_TO_SEGID(sbdf_shadow); devid = PCI_SBDF_TO_DEVID(sbdf_shadow); for_each_pci_segment(pci_seg) { if (pci_seg->id != seg) Loading
drivers/iommu/amd/init.c +6 −3 Original line number Diff line number Diff line Loading @@ -848,10 +848,11 @@ static void __init free_command_buffer(struct amd_iommu *iommu) void *__init iommu_alloc_4k_pages(struct amd_iommu *iommu, gfp_t gfp, size_t size) { int nid = iommu->dev ? dev_to_node(&iommu->dev->dev) : NUMA_NO_NODE; void *buf; size = PAGE_ALIGN(size); buf = iommu_alloc_pages_sz(gfp, size); buf = iommu_alloc_pages_node_sz(nid, gfp, size); if (!buf) return NULL; if (check_feature(FEATURE_SNP) && Loading Loading @@ -954,14 +955,16 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu) static int iommu_init_ga_log(struct amd_iommu *iommu) { int nid = iommu->dev ? dev_to_node(&iommu->dev->dev) : NUMA_NO_NODE; if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir)) return 0; iommu->ga_log = iommu_alloc_pages_sz(GFP_KERNEL, GA_LOG_SIZE); iommu->ga_log = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, GA_LOG_SIZE); if (!iommu->ga_log) goto err_out; iommu->ga_log_tail = iommu_alloc_pages_sz(GFP_KERNEL, 8); iommu->ga_log_tail = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, 8); if (!iommu->ga_log_tail) goto err_out; Loading
drivers/iommu/amd/iommu.c +33 −10 Original line number Diff line number Diff line Loading @@ -403,11 +403,12 @@ struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid) return NULL; } static int clone_alias(struct pci_dev *pdev, u16 alias, void *data) static int clone_alias(struct pci_dev *pdev_origin, u16 alias, void *data) { struct dev_table_entry new; struct amd_iommu *iommu; struct iommu_dev_data *dev_data, *alias_data; struct pci_dev *pdev = data; u16 devid = pci_dev_id(pdev); int ret = 0; Loading Loading @@ -454,9 +455,9 @@ static void clone_aliases(struct amd_iommu *iommu, struct device *dev) * part of the PCI DMA aliases if it's bus differs * from the original device. */ clone_alias(pdev, iommu->pci_seg->alias_table[pci_dev_id(pdev)], NULL); clone_alias(pdev, iommu->pci_seg->alias_table[pci_dev_id(pdev)], pdev); pci_for_each_dma_alias(pdev, clone_alias, NULL); pci_for_each_dma_alias(pdev, clone_alias, pdev); } static void setup_aliases(struct amd_iommu *iommu, struct device *dev) Loading Loading @@ -2991,13 +2992,17 @@ static bool amd_iommu_capable(struct device *dev, enum iommu_cap cap) return amdr_ivrs_remap_support; case IOMMU_CAP_ENFORCE_CACHE_COHERENCY: return true; case IOMMU_CAP_DEFERRED_FLUSH: return true; case IOMMU_CAP_DIRTY_TRACKING: { struct amd_iommu *iommu = get_amd_iommu_from_dev(dev); return amd_iommu_hd_support(iommu); } case IOMMU_CAP_PCI_ATS_SUPPORTED: { struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev); return amd_iommu_iotlb_sup && (dev_data->flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP); } default: break; } Loading Loading @@ -3179,26 +3184,44 @@ const struct iommu_ops amd_iommu_ops = { static struct irq_chip amd_ir_chip; static DEFINE_SPINLOCK(iommu_table_lock); static int iommu_flush_dev_irt(struct pci_dev *unused, u16 devid, void *data) { int ret; struct iommu_cmd cmd; struct amd_iommu *iommu = data; build_inv_irt(&cmd, devid); ret = __iommu_queue_command_sync(iommu, &cmd, true); return ret; } static void iommu_flush_irt_and_complete(struct amd_iommu *iommu, u16 devid) { int ret; u64 data; unsigned long flags; struct iommu_cmd cmd, cmd2; struct iommu_cmd cmd; struct pci_dev *pdev = NULL; struct iommu_dev_data *dev_data = search_dev_data(iommu, devid); if (iommu->irtcachedis_enabled) return; build_inv_irt(&cmd, devid); if (dev_data && dev_data->dev && dev_is_pci(dev_data->dev)) pdev = to_pci_dev(dev_data->dev); raw_spin_lock_irqsave(&iommu->lock, flags); data = get_cmdsem_val(iommu); build_completion_wait(&cmd2, iommu, data); build_completion_wait(&cmd, iommu, data); ret = __iommu_queue_command_sync(iommu, &cmd, true); if (pdev) ret = pci_for_each_dma_alias(pdev, iommu_flush_dev_irt, iommu); else ret = iommu_flush_dev_irt(NULL, devid, iommu); if (ret) goto out_err; ret = __iommu_queue_command_sync(iommu, &cmd2, false); ret = __iommu_queue_command_sync(iommu, &cmd, false); if (ret) goto out_err; raw_spin_unlock_irqrestore(&iommu->lock, flags); Loading