Skip to content

Commit a7391ad

Browse files
committed
Merge tag 'iomm-fixes-v5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel: "IOMMU core: - Fix for a regression which could cause NULL-ptr dereferences Arm SMMU: - Fix off-by-one in SMMUv3 SVA TLB invalidation - Disable large mappings to workaround nvidia erratum Intel VT-d: - Handle PCI stop marker messages in IOMMU driver to meet the requirement of I/O page fault handling framework. - Calculate a feasible mask for non-aligned page-selective IOTLB invalidation. Apple DART IOMMU: - Fix potential NULL-ptr dereference - Set module owner" * tag 'iomm-fixes-v5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu: Make sysfs robust for non-API groups iommu/dart: Add missing module owner to ops structure iommu/dart: check return value after calling platform_get_resource() iommu/vt-d: Drop stop marker messages iommu/vt-d: Calculate mask for non-aligned flushes iommu: arm-smmu: disable large page mappings for Nvidia arm-smmu iommu/arm-smmu-v3: Fix size calculation in arm_smmu_mm_invalidate_range()
2 parents 3118d7a + 392bf51 commit a7391ad

File tree

6 files changed

+79
-10
lines changed

6 files changed

+79
-10
lines changed

drivers/iommu/apple-dart.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,7 @@ static const struct iommu_ops apple_dart_iommu_ops = {
773773
.get_resv_regions = apple_dart_get_resv_regions,
774774
.put_resv_regions = generic_iommu_put_resv_regions,
775775
.pgsize_bitmap = -1UL, /* Restricted during dart probe */
776+
.owner = THIS_MODULE,
776777
.default_domain_ops = &(const struct iommu_domain_ops) {
777778
.attach_dev = apple_dart_attach_dev,
778779
.detach_dev = apple_dart_detach_dev,
@@ -859,16 +860,15 @@ static int apple_dart_probe(struct platform_device *pdev)
859860
dart->dev = dev;
860861
spin_lock_init(&dart->lock);
861862

862-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
863+
dart->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
864+
if (IS_ERR(dart->regs))
865+
return PTR_ERR(dart->regs);
866+
863867
if (resource_size(res) < 0x4000) {
864868
dev_err(dev, "MMIO region too small (%pr)\n", res);
865869
return -EINVAL;
866870
}
867871

868-
dart->regs = devm_ioremap_resource(dev, res);
869-
if (IS_ERR(dart->regs))
870-
return PTR_ERR(dart->regs);
871-
872872
dart->irq = platform_get_irq(pdev, 0);
873873
if (dart->irq < 0)
874874
return -ENODEV;

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,14 @@ static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn,
183183
{
184184
struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn);
185185
struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
186-
size_t size = end - start + 1;
186+
size_t size;
187+
188+
/*
189+
* The mm_types defines vm_end as the first byte after the end address,
190+
* different from IOMMU subsystem using the last address of an address
191+
* range. So do a simple translation here by calculating size correctly.
192+
*/
193+
size = end - start;
187194

188195
if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM))
189196
arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid,

drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,34 @@ static void nvidia_smmu_probe_finalize(struct arm_smmu_device *smmu, struct devi
258258
dev_name(dev), err);
259259
}
260260

261+
static int nvidia_smmu_init_context(struct arm_smmu_domain *smmu_domain,
262+
struct io_pgtable_cfg *pgtbl_cfg,
263+
struct device *dev)
264+
{
265+
struct arm_smmu_device *smmu = smmu_domain->smmu;
266+
const struct device_node *np = smmu->dev->of_node;
267+
268+
/*
269+
* Tegra194 and Tegra234 SoCs have the erratum that causes walk cache
270+
* entries to not be invalidated correctly. The problem is that the walk
271+
* cache index generated for IOVA is not same across translation and
272+
* invalidation requests. This is leading to page faults when PMD entry
273+
* is released during unmap and populated with new PTE table during
274+
* subsequent map request. Disabling large page mappings avoids the
275+
* release of PMD entry and avoid translations seeing stale PMD entry in
276+
* walk cache.
277+
* Fix this by limiting the page mappings to PAGE_SIZE on Tegra194 and
278+
* Tegra234.
279+
*/
280+
if (of_device_is_compatible(np, "nvidia,tegra234-smmu") ||
281+
of_device_is_compatible(np, "nvidia,tegra194-smmu")) {
282+
smmu->pgsize_bitmap = PAGE_SIZE;
283+
pgtbl_cfg->pgsize_bitmap = smmu->pgsize_bitmap;
284+
}
285+
286+
return 0;
287+
}
288+
261289
static const struct arm_smmu_impl nvidia_smmu_impl = {
262290
.read_reg = nvidia_smmu_read_reg,
263291
.write_reg = nvidia_smmu_write_reg,
@@ -268,10 +296,12 @@ static const struct arm_smmu_impl nvidia_smmu_impl = {
268296
.global_fault = nvidia_smmu_global_fault,
269297
.context_fault = nvidia_smmu_context_fault,
270298
.probe_finalize = nvidia_smmu_probe_finalize,
299+
.init_context = nvidia_smmu_init_context,
271300
};
272301

273302
static const struct arm_smmu_impl nvidia_smmu_single_impl = {
274303
.probe_finalize = nvidia_smmu_probe_finalize,
304+
.init_context = nvidia_smmu_init_context,
275305
};
276306

277307
struct arm_smmu_device *nvidia_smmu_impl_init(struct arm_smmu_device *smmu)

drivers/iommu/intel/iommu.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,8 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
15881588
unsigned long pfn, unsigned int pages,
15891589
int ih, int map)
15901590
{
1591-
unsigned int mask = ilog2(__roundup_pow_of_two(pages));
1591+
unsigned int aligned_pages = __roundup_pow_of_two(pages);
1592+
unsigned int mask = ilog2(aligned_pages);
15921593
uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
15931594
u16 did = domain->iommu_did[iommu->seq_id];
15941595

@@ -1600,10 +1601,30 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
16001601
if (domain_use_first_level(domain)) {
16011602
qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, pages, ih);
16021603
} else {
1604+
unsigned long bitmask = aligned_pages - 1;
1605+
1606+
/*
1607+
* PSI masks the low order bits of the base address. If the
1608+
* address isn't aligned to the mask, then compute a mask value
1609+
* needed to ensure the target range is flushed.
1610+
*/
1611+
if (unlikely(bitmask & pfn)) {
1612+
unsigned long end_pfn = pfn + pages - 1, shared_bits;
1613+
1614+
/*
1615+
* Since end_pfn <= pfn + bitmask, the only way bits
1616+
* higher than bitmask can differ in pfn and end_pfn is
1617+
* by carrying. This means after masking out bitmask,
1618+
* high bits starting with the first set bit in
1619+
* shared_bits are all equal in both pfn and end_pfn.
1620+
*/
1621+
shared_bits = ~(pfn ^ end_pfn) & ~bitmask;
1622+
mask = shared_bits ? __ffs(shared_bits) : BITS_PER_LONG;
1623+
}
1624+
16031625
/*
16041626
* Fallback to domain selective flush if no PSI support or
1605-
* the size is too big. PSI requires page size to be 2 ^ x,
1606-
* and the base address is naturally aligned to the size.
1627+
* the size is too big.
16071628
*/
16081629
if (!cap_pgsel_inv(iommu->cap) ||
16091630
mask > cap_max_amask_val(iommu->cap))

drivers/iommu/intel/svm.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,10 @@ static irqreturn_t prq_event_thread(int irq, void *d)
757757
goto bad_req;
758758
}
759759

760+
/* Drop Stop Marker message. No need for a response. */
761+
if (unlikely(req->lpig && !req->rd_req && !req->wr_req))
762+
goto prq_advance;
763+
760764
if (!svm || svm->pasid != req->pasid) {
761765
/*
762766
* It can't go away, because the driver is not permitted

drivers/iommu/iommu.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,13 @@ int iommu_get_group_resv_regions(struct iommu_group *group,
506506
list_for_each_entry(device, &group->devices, list) {
507507
struct list_head dev_resv_regions;
508508

509+
/*
510+
* Non-API groups still expose reserved_regions in sysfs,
511+
* so filter out calls that get here that way.
512+
*/
513+
if (!device->dev->iommu)
514+
break;
515+
509516
INIT_LIST_HEAD(&dev_resv_regions);
510517
iommu_get_resv_regions(device->dev, &dev_resv_regions);
511518
ret = iommu_insert_device_resv_regions(&dev_resv_regions, head);
@@ -3019,7 +3026,7 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
30193026
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
30203027
return -EACCES;
30213028

3022-
if (WARN_ON(!group))
3029+
if (WARN_ON(!group) || !group->default_domain)
30233030
return -EINVAL;
30243031

30253032
if (sysfs_streq(buf, "identity"))

0 commit comments

Comments
 (0)