[PATCH] drm/amdkfd: fix signal page mmap PFN for GTT-backed event pages.
__pa(kernel_address) is invalid for vmap'd GTT kmap addresses. Record
page->user_pfn at setup (virt_to_page / vmalloc_to_pfn) and use it in
kfd_event_mmap() instead of __pa().
Signed-off-by: Yongqiang Sun
---
drivers/gpu/drm/amd/amdkfd/kfd_events.c | 16 ++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index e9be798c0a2b..6e0beacca81e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -21,8 +21,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include
#include
#include
+#include
#include
#include
#include
@@ -54,6 +56,7 @@ struct kfd_event_waiter {
struct kfd_signal_page {
uint64_t *kernel_address;
uint64_t __user *user_address;
+ unsigned long user_pfn;
bool need_to_free_pages;
};
@@ -82,6 +85,7 @@ static struct kfd_signal_page *allocate_signal_page(struct
kfd_process *p)
page->kernel_address = backing_store;
page->need_to_free_pages = true;
+ page->user_pfn = page_to_pfn(virt_to_page(backing_store));
pr_debug("Allocated new event signal page at %p, for process %p\n",
page, p);
@@ -349,6 +353,11 @@ static int kfd_event_page_set(struct kfd_process *p, void
*kernel_address,
KFD_SIGNAL_EVENT_LIMIT * 8);
page->kernel_address = kernel_address;
+ /* kmap for GTT is vmap-backed; do not use __pa() on kernel_address */
+ if (is_vmalloc_addr(kernel_address))
+ page->user_pfn = vmalloc_to_pfn(kernel_address);
+ else
+ page->user_pfn = page_to_pfn(virt_to_page(kernel_address));
p->signal_page = page;
p->signal_mapped_size = size;
@@ -1087,8 +1096,11 @@ int kfd_event_mmap(struct kfd_process *p, struct
vm_area_struct *vma)
return -EINVAL;
}
- pfn = __pa(page->kernel_address);
- pfn >>= PAGE_SHIFT;
+ if (!page->user_pfn) {
+ pr_err("signal page has no recorded PFN\n");
+ return -EINVAL;
+ }
+ pfn = page->user_pfn;
vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE
| VM_DONTDUMP | VM_PFNMAP);
--
2.43.0
[PATCH] drm/amdkfd: fix signal page mmap PFN for GTT-backed event pages.
__pa(kernel_address) is invalid for vmap'd GTT kmap addresses. Record
page->user_pfn at setup (virt_to_page / vmalloc_to_pfn) and use it in
kfd_event_mmap() instead of __pa().
Change-Id: I61061ab280850afa776191c30ba90a475afab46d
Signed-off-by: "Sun, Yongqiang"
---
drivers/gpu/drm/amd/amdkfd/kfd_events.c | 16 ++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index e9be798c0a2b..6e0beacca81e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -21,8 +21,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include
#include
#include
+#include
#include
#include
#include
@@ -54,6 +56,7 @@ struct kfd_event_waiter {
struct kfd_signal_page {
uint64_t *kernel_address;
uint64_t __user *user_address;
+ unsigned long user_pfn;
bool need_to_free_pages;
};
@@ -82,6 +85,7 @@ static struct kfd_signal_page *allocate_signal_page(struct
kfd_process *p)
page->kernel_address = backing_store;
page->need_to_free_pages = true;
+ page->user_pfn = page_to_pfn(virt_to_page(backing_store));
pr_debug("Allocated new event signal page at %p, for process %p\n",
page, p);
@@ -349,6 +353,11 @@ static int kfd_event_page_set(struct kfd_process *p, void
*kernel_address,
KFD_SIGNAL_EVENT_LIMIT * 8);
page->kernel_address = kernel_address;
+ /* kmap for GTT is vmap-backed; do not use __pa() on kernel_address */
+ if (is_vmalloc_addr(kernel_address))
+ page->user_pfn = vmalloc_to_pfn(kernel_address);
+ else
+ page->user_pfn = page_to_pfn(virt_to_page(kernel_address));
p->signal_page = page;
p->signal_mapped_size = size;
@@ -1087,8 +1096,11 @@ int kfd_event_mmap(struct kfd_process *p, struct
vm_area_struct *vma)
return -EINVAL;
}
- pfn = __pa(page->kernel_address);
- pfn >>= PAGE_SHIFT;
+ if (!page->user_pfn) {
+ pr_err("signal page has no recorded PFN\n");
+ return -EINVAL;
+ }
+ pfn = page->user_pfn;
vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE
| VM_DONTDUMP | VM_PFNMAP);
--
2.43.0
