aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2018-12-19 03:52:29 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2018-12-21 00:20:46 -0500
commit58629c0dc34904d135af944d120eb23165ec3b61 (patch)
treec6e96ae78213fc95c6f7181047ee68210d6440d1
parent135ef954051b102870a8d47a8eb822af1f1b1ec1 (diff)
powerpc/powernv/npu: Fault user page into the hypervisor's pagetable
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>
-rw-r--r--arch/powerpc/platforms/powernv/npu-dma.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c
index b713727663e2..d7f742ed48ba 100644
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -1132,6 +1132,8 @@ int pnv_npu2_handle_fault(struct npu_context *context, uintptr_t *ea,
1132 u64 rc = 0, result = 0; 1132 u64 rc = 0, result = 0;
1133 int i, is_write; 1133 int i, is_write;
1134 struct page *page[1]; 1134 struct page *page[1];
1135 const char __user *u;
1136 char c;
1135 1137
1136 /* mmap_sem should be held so the struct_mm must be present */ 1138 /* mmap_sem should be held so the struct_mm must be present */
1137 struct mm_struct *mm = context->mm; 1139 struct mm_struct *mm = context->mm;
@@ -1144,18 +1146,17 @@ int pnv_npu2_handle_fault(struct npu_context *context, uintptr_t *ea,
1144 is_write ? FOLL_WRITE : 0, 1146 is_write ? FOLL_WRITE : 0,
1145 page, NULL, NULL); 1147 page, NULL, NULL);
1146 1148
1147 /*
1148 * To support virtualised environments we will have to do an
1149 * access to the page to ensure it gets faulted into the
1150 * hypervisor. For the moment virtualisation is not supported in
1151 * other areas so leave the access out.
1152 */
1153 if (rc != 1) { 1149 if (rc != 1) {
1154 status[i] = rc; 1150 status[i] = rc;
1155 result = -EFAULT; 1151 result = -EFAULT;
1156 continue; 1152 continue;
1157 } 1153 }
1158 1154
1155 /* Make sure partition scoped tree gets a pte */
1156 u = page_address(page[0]);
1157 if (__get_user(c, u))
1158 result = -EFAULT;
1159
1159 status[i] = 0; 1160 status[i] = 0;
1160 put_page(page[0]); 1161 put_page(page[0]);
1161 } 1162 }