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

Reply via email to