Cc: linuxppc-dev@lists.ozlabs.org, linux-ker...@vger.kernel.org, Having System pagesize < IOMMU pagesize may cause a page owned by another process/VM to be written by a buggy driver / device.
As it's intended to use DDW for indirect mapping, it's possible to get a configuration where (PAGE_SIZE = 4k) < (IOMMU_PAGE_SIZE() = 64k). To avoid this, make sure create_ddw() can only use pagesize <= PAGE_SIZE. Signed-off-by: Leonardo Bras <leobra...@gmail.com> --- arch/powerpc/platforms/pseries/iommu.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 9db3927607a4..4eff3a6a441e 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -1206,17 +1206,20 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) goto out_failed; } } - if (query.page_size & 4) { - page_shift = 24; /* 16MB */ - } else if (query.page_size & 2) { + + /* Choose the biggest pagesize available <= PAGE_SHIFT */ + if ((query.page_size & 4)) { + page_shift = 24; /* 16MB - Hugepages */ + } else if ((query.page_size & 2) && PAGE_SHIFT >= 16) { page_shift = 16; /* 64kB */ - } else if (query.page_size & 1) { + } else if ((query.page_size & 1) && PAGE_SHIFT >= 12) { page_shift = 12; /* 4kB */ } else { dev_dbg(&dev->dev, "no supported direct page size in mask %x", query.page_size); goto out_failed; } + /* verify the window * number of ptes will map the partition */ /* check largest block * page size > max memory hotplug addr */ max_addr = ddw_memory_hotplug_max(); -- 2.25.4