arch_perf_out_copy_user() allows copying arbitrary data from user memory.
arch_perf_out_copy_user() does not get passed a user pointer, so at the moment we need to create one. Because the address it gets passed is arbitrary, using uaddr_to_user_ptr_safe() is not appropriate. Use uaddr_to_user_ptr() instead, until we find a more permanent solution.
Currently, the only user of arch_perf_out_copy_user() is perf_output_sample_ustack(), which reads a certain amount of data from the user stack as sample for PERF_SAMPLE_STACK_USER. It should be possible to get this function to pass a full user pointer to the copy routine, though this creates some complications:
- DEFINE_OUTPUT_COPY() would need to handle either a kernel or user pointer (may need a new macro).
- perf_output_sample_ustack() would need to obtain the actual stack pointer, but perf_user_stack_pointer() currently returns an unsigned long. Most likely this means changing user_stack_pointer() to return a user_uintptr_t, with an appropriate implementation in PCuABI.
- Compat would need to be handled carefully, probably using compat_ptr() to create a valid user pointer.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- kernel/events/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/events/internal.h b/kernel/events/internal.h index a68cd0b99b04..d1a7c0030c11 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h @@ -199,7 +199,7 @@ arch_perf_out_copy_user(void *dst, const void *src, unsigned long n) unsigned long ret;
pagefault_disable(); - ret = __copy_from_user_inatomic(dst, uaddr_to_user_ptr_safe((ptraddr_t)src), n); + ret = __copy_from_user_inatomic(dst, uaddr_to_user_ptr((ptraddr_t)src), n); pagefault_enable();
return ret;