X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=lib%2Fringbuffer%2Fbackend.h;h=b362a04a436bfe64c640f694968032fb7de5aa32;hb=8ec496cfb24b29a54c057a332fc91e761994999e;hp=c0142071666bed5df347b3ab96d3762e9830ddf9;hpb=5671a6610b06175832338ed78db486b59bc5246c;p=lttng-modules.git diff --git a/lib/ringbuffer/backend.h b/lib/ringbuffer/backend.h index c0142071..b362a04a 100644 --- a/lib/ringbuffer/backend.h +++ b/lib/ringbuffer/backend.h @@ -83,7 +83,7 @@ lib_ring_buffer_read_offset_address(struct lib_ring_buffer_backend *bufb, * backend-specific memcpy() operation. Calls the slow path (_ring_buffer_write) * if copy is crossing a page boundary. */ -static inline +static inline __attribute__((always_inline)) void lib_ring_buffer_write(const struct lib_ring_buffer_config *config, struct lib_ring_buffer_ctx *ctx, const void *src, size_t len) @@ -168,7 +168,7 @@ void lib_ring_buffer_memset(const struct lib_ring_buffer_config *config, * terminating character is found in @src. Returns the number of bytes * copied. Does *not* terminate @dest with NULL terminating character. */ -static inline +static inline __attribute__((always_inline)) size_t lib_ring_buffer_do_strcpy(const struct lib_ring_buffer_config *config, char *dest, const char *src, size_t len) { @@ -199,7 +199,7 @@ size_t lib_ring_buffer_do_strcpy(const struct lib_ring_buffer_config *config, * directly without having the src pointer checked with access_ok() * previously. */ -static inline +static inline __attribute__((always_inline)) size_t lib_ring_buffer_do_strcpy_from_user_inatomic(const struct lib_ring_buffer_config *config, char *dest, const char __user *src, size_t len) { @@ -297,7 +297,7 @@ void lib_ring_buffer_strcpy(const struct lib_ring_buffer_config *config, * (_ring_buffer_write_from_user_inatomic) if copy is crossing a page boundary. * Disable the page fault handler to ensure we never try to take the mmap_sem. */ -static inline +static inline __attribute__((always_inline)) void lib_ring_buffer_copy_from_user_inatomic(const struct lib_ring_buffer_config *config, struct lib_ring_buffer_ctx *ctx, const void __user *src, size_t len) @@ -334,8 +334,7 @@ void lib_ring_buffer_copy_from_user_inatomic(const struct lib_ring_buffer_config rpages->p[index].virt + (offset & ~PAGE_MASK), src, len); if (unlikely(ret > 0)) { - len -= (pagecpy - ret); - offset += (pagecpy - ret); + /* Copy failed. */ goto fill_buffer; } } else { @@ -479,4 +478,29 @@ unsigned long lib_ring_buffer_get_records_unread( return records_unread; } +/* + * We use __copy_from_user_inatomic to copy userspace data after + * checking with access_ok() and disabling page faults. + * + * Return 0 if OK, nonzero on error. + */ +static inline +unsigned long lib_ring_buffer_copy_from_user_check_nofault(void *dest, + const void __user *src, + unsigned long len) +{ + unsigned long ret; + mm_segment_t old_fs; + + if (!access_ok(VERIFY_READ, src, len)) + return 1; + old_fs = get_fs(); + set_fs(KERNEL_DS); + pagefault_disable(); + ret = __copy_from_user_inatomic(dest, src, len); + pagefault_enable(); + set_fs(old_fs); + return ret; +} + #endif /* _LIB_RING_BUFFER_BACKEND_H */