History

Merge tag 'iommu-fixes-v4.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull IOMMU fixes from Joerg Roedel: - fix a scheduling-while-atomic bug in the AMD IOMMU driver. It was found after the checker was enabled earlier. - a fix for the virtual APIC code in the AMD IOMMU driver which delivers device interrupts directly into KVM guests for assigned devices. - fixes for the recently merged lock-less page-table code for ARM. The redundant TLB syncs got reverted and locks added again around the TLB sync code. - fix for error handling in arm_smmu_add_device() - address sanitization fix for arm io-pgtable code * tag 'iommu-fixes-v4.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/amd: Fix schedule-while-atomic BUG in initialization code iommu/amd: Enable ga_log_intr when enabling guest_mode iommu/io-pgtable: Sanitise map/unmap addresses iommu/arm-smmu: Fix the error path in arm_smmu_add_device Revert "iommu/io-pgtable: Avoid redundant TLB syncs" iommu/mtk: Avoid redundant TLB syncs locally iommu/arm-smmu: Reintroduce locking around TLB sync operations

Linus Torvalds committed 9 years ago

Commit 83b89ea2 parents 8145f37 74ddda78 files · +36 −14Browse files

Unified · Split

8 files
  1. drivers/iommu/amd_iommu.c +1 −0
  2. drivers/iommu/amd_iommu_init.c +1 −1
  3. drivers/iommu/arm-smmu.c +13 −5
  4. drivers/iommu/io-pgtable-arm-v7s.c +6 −0
  5. drivers/iommu/io-pgtable-arm.c +7 −0
  6. drivers/iommu/io-pgtable.h +1 −8
  7. drivers/iommu/mtk_iommu.c +6 −0
  8. drivers/iommu/mtk_iommu.h +1 −0
drivers/iommu/amd_iommu.c+1−0
@@ -4452,6 +4452,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info) · 4451 unmodified lines
44524452 /* Setting */
44534453 irte->hi.fields.ga_root_ptr = (pi_data->base >> 12);
44544454 irte->hi.fields.vector = vcpu_pi_info->vector;
4455+ irte->lo.fields_vapic.ga_log_intr = 1;
44554456 irte->lo.fields_vapic.guest_mode = 1;
44564457 irte->lo.fields_vapic.ga_tag = pi_data->ga_tag;
44574458
drivers/iommu/amd_iommu_init.c+1−1
@@ -2440,11 +2440,11 @@ static int __init state_next(void) · 2439 unmodified lines
24402440 break;
24412441 case IOMMU_ACPI_FINISHED:
24422442 early_enable_iommus();
2443− register_syscore_ops(&amd_iommu_syscore_ops);
24442443 x86_platform.iommu_shutdown = disable_iommus;
24452444 init_state = IOMMU_ENABLED;
24462445 break;
24472446 case IOMMU_ENABLED:
2447+ register_syscore_ops(&amd_iommu_syscore_ops);
24482448 ret = amd_iommu_init_pci();
24492449 init_state = ret ? IOMMU_INIT_ERROR : IOMMU_PCI_INIT;
24502450 enable_iommus_v2();
drivers/iommu/arm-smmu.c+13−5
@@ -400,6 +400,8 @@ struct arm_smmu_device { · 399 unmodified lines
400400
401401 u32 cavium_id_base; /* Specific to Cavium */
402402
403+ spinlock_t global_sync_lock;
404+
403405 /* IOMMU core code handle */
404406 struct iommu_device iommu;
405407 };
@@ -436,7 +438,7 @@ struct arm_smmu_domain { · 30 unmodified lines
436438 struct arm_smmu_cfg cfg;
437439 enum arm_smmu_domain_stage stage;
438440 struct mutex init_mutex; /* Protects smmu pointer */
439− spinlock_t cb_lock; /* Serialises ATS1* ops */
441+ spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */
440442 struct iommu_domain domain;
441443 };
442444
@@ -602,9 +604,12 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, · 159 unmodified lines
602604 static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu)
603605 {
604606 void __iomem *base = ARM_SMMU_GR0(smmu);
607+ unsigned long flags;
605608
609+ spin_lock_irqsave(&smmu->global_sync_lock, flags);
606610 __arm_smmu_tlb_sync(smmu, base + ARM_SMMU_GR0_sTLBGSYNC,
607611 base + ARM_SMMU_GR0_sTLBGSTATUS);
612+ spin_unlock_irqrestore(&smmu->global_sync_lock, flags);
608613 }
609614
610615 static void arm_smmu_tlb_sync_context(void *cookie)
@@ -612,9 +617,12 @@ static void arm_smmu_tlb_sync_context(void *cookie) · 1 unmodified line
612617 struct arm_smmu_domain *smmu_domain = cookie;
613618 struct arm_smmu_device *smmu = smmu_domain->smmu;
614619 void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
620+ unsigned long flags;
615621
622+ spin_lock_irqsave(&smmu_domain->cb_lock, flags);
616623 __arm_smmu_tlb_sync(smmu, base + ARM_SMMU_CB_TLBSYNC,
617624 base + ARM_SMMU_CB_TLBSTATUS);
625+ spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
618626 }
619627
620628 static void arm_smmu_tlb_sync_vmid(void *cookie)
@@ -1511,7 +1519,6 @@ static int arm_smmu_add_device(struct device *dev) · 890 unmodified lines
15111519
15121520 if (using_legacy_binding) {
15131521 ret = arm_smmu_register_legacy_master(dev, &smmu);
1514− fwspec = dev->iommu_fwspec;
15151522 if (ret)
15161523 goto out_free;
15171524 } else if (fwspec && fwspec->ops == &arm_smmu_ops) {
@@ -1550,15 +1557,15 @@ static int arm_smmu_add_device(struct device *dev) · 32 unmodified lines
15501557
15511558 ret = arm_smmu_master_alloc_smes(dev);
15521559 if (ret)
1553− goto out_free;
1560+ goto out_cfg_free;
15541561
15551562 iommu_device_link(&smmu->iommu, dev);
15561563
15571564 return 0;
15581565
1566+out_cfg_free:
1567+ kfree(cfg);
15591568 out_free:
1560− if (fwspec)
1561− kfree(fwspec->iommu_priv);
15621569 iommu_fwspec_free(dev);
15631570 return ret;
15641571 }
@@ -1925,6 +1932,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) · 360 unmodified lines
19251932
19261933 smmu->num_mapping_groups = size;
19271934 mutex_init(&smmu->stream_map_mutex);
1935+ spin_lock_init(&smmu->global_sync_lock);
19281936
19291937 if (smmu->version < ARM_SMMU_V2 || !(id & ID0_PTFS_NO_AARCH32)) {
19301938 smmu->features |= ARM_SMMU_FEAT_FMT_AARCH32_L;
drivers/iommu/io-pgtable-arm-v7s.c+6−0
@@ -479,6 +479,9 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova, · 478 unmodified lines
479479 if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
480480 return 0;
481481
482+ if (WARN_ON(upper_32_bits(iova) || upper_32_bits(paddr)))
483+ return -ERANGE;
484+
482485 ret = __arm_v7s_map(data, iova, paddr, size, prot, 1, data->pgd);
483486 /*
484487 * Synchronise all PTE updates for the new mapping before there's
@@ -659,6 +662,9 @@ static int arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova, · 174 unmodified lines
659662 struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops);
660663 size_t unmapped;
661664
665+ if (WARN_ON(upper_32_bits(iova)))
666+ return 0;
667+
662668 unmapped = __arm_v7s_unmap(data, iova, size, 1, data->pgd);
663669 if (unmapped)
664670 io_pgtable_tlb_sync(&data->iop);
drivers/iommu/io-pgtable-arm.c+7−0
@@ -452,6 +452,10 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, · 451 unmodified lines
452452 if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
453453 return 0;
454454
455+ if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) ||
456+ paddr >= (1ULL << data->iop.cfg.oas)))
457+ return -ERANGE;
458+
455459 prot = arm_lpae_prot_to_pte(data, iommu_prot);
456460 ret = __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep);
457461 /*
@@ -610,6 +614,9 @@ static int arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, · 152 unmodified lines
610614 arm_lpae_iopte *ptep = data->pgd;
611615 int lvl = ARM_LPAE_START_LVL(data);
612616
617+ if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias)))
618+ return 0;
619+
613620 unmapped = __arm_lpae_unmap(data, iova, size, lvl, ptep);
614621 if (unmapped)
615622 io_pgtable_tlb_sync(&data->iop);
drivers/iommu/io-pgtable.h+1−8
@@ -158,14 +158,12 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops); · 157 unmodified lines
158158 * @fmt: The page table format.
159159 * @cookie: An opaque token provided by the IOMMU driver and passed back to
160160 * any callback routines.
161− * @tlb_sync_pending: Private flag for optimising out redundant syncs.
162161 * @cfg: A copy of the page table configuration.
163162 * @ops: The page table operations in use for this set of page tables.
164163 */
165164 struct io_pgtable {
166165 enum io_pgtable_fmt fmt;
167166 void *cookie;
168− bool tlb_sync_pending;
169167 struct io_pgtable_cfg cfg;
170168 struct io_pgtable_ops ops;
171169 };
@@ -175,22 +173,17 @@ struct io_pgtable { · 3 unmodified lines
175173 static inline void io_pgtable_tlb_flush_all(struct io_pgtable *iop)
176174 {
177175 iop->cfg.tlb->tlb_flush_all(iop->cookie);
178− iop->tlb_sync_pending = true;
179176 }
180177
181178 static inline void io_pgtable_tlb_add_flush(struct io_pgtable *iop,
182179 unsigned long iova, size_t size, size_t granule, bool leaf)
183180 {
184181 iop->cfg.tlb->tlb_add_flush(iova, size, granule, leaf, iop->cookie);
185− iop->tlb_sync_pending = true;
186182 }
187183
188184 static inline void io_pgtable_tlb_sync(struct io_pgtable *iop)
189185 {
190− if (iop->tlb_sync_pending) {
191− iop->cfg.tlb->tlb_sync(iop->cookie);
192− iop->tlb_sync_pending = false;
193− }
186+ iop->cfg.tlb->tlb_sync(iop->cookie);
194187 }
195188
196189 /**
drivers/iommu/mtk_iommu.c+6−0
@@ -129,6 +129,7 @@ static void mtk_iommu_tlb_add_flush_nosync(unsigned long iova, size_t size, · 128 unmodified lines
129129 writel_relaxed(iova, data->base + REG_MMU_INVLD_START_A);
130130 writel_relaxed(iova + size - 1, data->base + REG_MMU_INVLD_END_A);
131131 writel_relaxed(F_MMU_INV_RANGE, data->base + REG_MMU_INVALIDATE);
132+ data->tlb_flush_active = true;
132133 }
133134
134135 static void mtk_iommu_tlb_sync(void *cookie)
@@ -137,6 +138,10 @@ static void mtk_iommu_tlb_sync(void *cookie) · 2 unmodified lines
137138 int ret;
138139 u32 tmp;
139140
141+ /* Avoid timing out if there's nothing to wait for */
142+ if (!data->tlb_flush_active)
143+ return;
144+
140145 ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, tmp,
141146 tmp != 0, 10, 100000);
142147 if (ret) {
@@ -146,6 +151,7 @@ static void mtk_iommu_tlb_sync(void *cookie) · 3 unmodified lines
146151 }
147152 /* Clear the CPE status */
148153 writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
154+ data->tlb_flush_active = false;
149155 }
150156
151157 static const struct iommu_gather_ops mtk_iommu_gather_ops = {
drivers/iommu/mtk_iommu.h+1−0
@@ -47,6 +47,7 @@ struct mtk_iommu_data { · 46 unmodified lines
4747 struct iommu_group *m4u_group;
4848 struct mtk_smi_iommu smi_imu; /* SMI larb iommu info */
4949 bool enable_4GB;
50+ bool tlb_flush_active;
5051
5152 struct iommu_device iommu;
5253 };

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t