]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
powerpc/powernv/npu: Fault user page into the hypervisor's pagetable
authorAlexey Kardashevskiy <aik@ozlabs.ru>
Thu, 14 Mar 2019 17:56:52 +0000 (14:56 -0300)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 1 Apr 2019 12:37:29 +0000 (14:37 +0200)
BugLink: https://bugs.launchpad.net/bugs/1819989
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 <aik@ozlabs.ru>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
(cherry picked from commit 58629c0dc34904d135af944d120eb23165ec3b61)
Signed-off-by: Jose Ricardo Ziviani <joserz@linux.ibm.com>
Acked-by: Kamal Mostafa <kamal@canonical.com>
Acked-by: Kleber Souza <kleber.souza@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
arch/powerpc/platforms/powernv/npu-dma.c

index 0440d0c01142919b7028bd9711581e5206be24dc..362e31c99f5c0cdd0b550f381f441f9f8c5f58f2 100644 (file)
@@ -918,6 +918,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;
@@ -930,18 +932,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]);
        }