When a page fault happens in a GPU, the GPU signals the OS and the GPU
driver calls the fault handler which populated a page table; this allows
the GPU to complete an ATS request.

On the bare metal get_user_pages() is enough as it adds a pte to
the kernel page table but under KVM the partition scope tree does not get
updated so ATS will still fail.

This reads a byte from an effective address which causes HV storage
interrupt and KVM updates the partition scope tree.

Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru>
---
 arch/powerpc/platforms/powernv/npu-dma.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/npu-dma.c 
b/arch/powerpc/platforms/powernv/npu-dma.c
index c6163b9..12b8421 100644
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -1133,6 +1133,8 @@ int pnv_npu2_handle_fault(struct npu_context *context, 
uintptr_t *ea,
        u64 rc = 0, result = 0;
        int i, is_write;
        struct page *page[1];
+       const char __user *u;
+       char c;
 
        /* mmap_sem should be held so the struct_mm must be present */
        struct mm_struct *mm = context->mm;
@@ -1145,18 +1147,17 @@ int pnv_npu2_handle_fault(struct npu_context *context, 
uintptr_t *ea,
                                        is_write ? FOLL_WRITE : 0,
                                        page, NULL, NULL);
 
-               /*
-                * To support virtualised environments we will have to do an
-                * access to the page to ensure it gets faulted into the
-                * hypervisor. For the moment virtualisation is not supported in
-                * other areas so leave the access out.
-                */
                if (rc != 1) {
                        status[i] = rc;
                        result = -EFAULT;
                        continue;
                }
 
+               /* Make sure partition scoped tree gets a pte */
+               u = page_address(page[0]);
+               if (__get_user(c, u))
+                       result = -EFAULT;
+
                status[i] = 0;
                put_page(page[0]);
        }
-- 
2.17.1

Reply via email to