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>
This commit is contained in:
Alexey Kardashevskiy 2018-12-19 19:52:29 +11:00 committed by Michael Ellerman
parent 135ef95405
commit 58629c0dc3

View File

@ -1132,6 +1132,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;
@ -1144,18 +1146,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]);
}