sPAPR allows only page_shift from VFIO_IOMMU_SPAPR_TCE_GET_INFO ioctl.
However, Linux 4.17 or before returns incorrect page_shift for Power9.
I added the code for retrying creation of sPAPR DMA window.

Signed-off-by: Takeshi Yoshimura <[email protected]>
---
 lib/librte_eal/linux/eal/eal_vfio.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/linux/eal/eal_vfio.c 
b/lib/librte_eal/linux/eal/eal_vfio.c
index 6892a2c14..f16c5c3c0 100644
--- a/lib/librte_eal/linux/eal/eal_vfio.c
+++ b/lib/librte_eal/linux/eal/eal_vfio.c
@@ -1448,9 +1448,29 @@ vfio_spapr_create_new_dma_window(int vfio_container_fd,
        /* create new DMA window */
        ret = ioctl(vfio_container_fd, VFIO_IOMMU_SPAPR_TCE_CREATE, create);
        if (ret) {
-               RTE_LOG(ERR, EAL, "  cannot create new DMA window, "
-                               "error %i (%s)\n", errno, strerror(errno));
-               return -1;
+               /* try possible page_shift and levels for workaround */
+               uint32_t levels;
+
+               for (levels = 1; levels <= info.ddw.levels; levels++) {
+                       uint32_t pgsizes = info.ddw.pgsizes;
+
+                       while (pgsizes != 0) {
+                               create->page_shift = 31 - 
__builtin_clz(pgsizes);
+                               create->levels = levels;
+                               ret = ioctl(vfio_container_fd,
+                                       VFIO_IOMMU_SPAPR_TCE_CREATE, create);
+                               if (!ret)
+                                       break;
+                               pgsizes &= ~(1 << create->page_shift);
+                       }
+                       if (!ret)
+                               break;
+               }
+               if (ret) {
+                       RTE_LOG(ERR, EAL, "  cannot create new DMA window, "
+                                       "error %i (%s)\n", errno, 
strerror(errno));
+                       return -1;
+               }
        }
 
        if (create->start_addr != 0) {
-- 
2.17.1

Reply via email to