1 /* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
7 * Copyright (C) 2008-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 #include <linux/module.h>
11 #include <linux/tracepoint.h>
12 #include <linux/uaccess.h>
13 #include <linux/gfp.h>
15 #include <linux/proc_fs.h>
16 #include <linux/slab.h>
18 #include <linux/miscdevice.h>
19 #include <wrapper/vmalloc.h>
20 #include <lttng-events.h>
22 #define TP_MODULE_NOAUTOLOAD
23 #define LTTNG_PACKAGE_BUILD
24 #define CREATE_TRACE_POINTS
25 #define TRACE_INCLUDE_PATH instrumentation/events/lttng-module
26 #define TRACE_INCLUDE_FILE lttng
27 #define LTTNG_INSTRUMENTATION
29 #include <instrumentation/events/lttng-module/lttng.h>
31 /* Events written through logger are truncated at 1024 bytes */
32 #define LTTNG_LOGGER_COUNT_MAX 1024
33 #define LTTNG_LOGGER_FILE "lttng-logger"
35 DEFINE_TRACE(lttng_logger
);
37 static struct proc_dir_entry
*lttng_logger_dentry
;
40 * lttng_logger_write - write a userspace string into the trace system
42 * @user_buf: user string
43 * @count: length to copy
44 * @ppos: file position
46 * Copy a userspace string into a trace event named "lttng:logger".
47 * Copies at most @count bytes into the event "msg" dynamic array.
48 * Truncates the count at LTTNG_LOGGER_COUNT_MAX. Returns the number of
49 * bytes copied from the source.
50 * Return -1 on error, with EFAULT errno.
53 ssize_t
lttng_logger_write(struct file
*file
, const char __user
*user_buf
,
54 size_t count
, loff_t
*ppos
)
57 unsigned long uaddr
= (unsigned long) user_buf
;
58 struct page
*pages
[2];
63 if (unlikely(count
> LTTNG_LOGGER_COUNT_MAX
))
64 count
= LTTNG_LOGGER_COUNT_MAX
;
66 /* How many pages are we dealing with ? */
67 if (unlikely((uaddr
& PAGE_MASK
) != ((uaddr
+ count
) & PAGE_MASK
)))
70 /* Pin userspace pages */
71 ret
= get_user_pages_fast(uaddr
, nr_pages
, 0, pages
);
72 if (unlikely(ret
< nr_pages
)) {
82 trace_lttng_logger(user_buf
, count
);
86 for (i
= 0; i
< nr_pages
; i
++)
92 static const struct file_operations lttng_logger_operations
= {
93 .write
= lttng_logger_write
,
97 * Linux 5.6 introduced a separate proc_ops struct for /proc operations
98 * to decouple it from the vfs.
100 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
101 static const struct proc_ops lttng_logger_proc_ops
= {
102 .proc_write
= lttng_logger_write
,
105 #define lttng_logger_proc_ops lttng_logger_operations
108 static struct miscdevice logger_dev
= {
109 .minor
= MISC_DYNAMIC_MINOR
,
110 .name
= "lttng-logger",
112 .fops
= <tng_logger_operations
115 int __init
lttng_logger_init(void)
119 wrapper_vmalloc_sync_mappings();
121 /* /dev/lttng-logger */
122 ret
= misc_register(&logger_dev
);
124 printk(KERN_ERR
"Error creating LTTng logger device\n");
128 /* /proc/lttng-logger */
129 lttng_logger_dentry
= proc_create_data(LTTNG_LOGGER_FILE
,
130 S_IRUGO
| S_IWUGO
, NULL
,
131 <tng_logger_proc_ops
, NULL
);
132 if (!lttng_logger_dentry
) {
133 printk(KERN_ERR
"Error creating LTTng logger proc file\n");
139 ret
= __lttng_events_init__lttng();
145 remove_proc_entry("lttng-logger", NULL
);
147 misc_deregister(&logger_dev
);
152 void lttng_logger_exit(void)
154 __lttng_events_exit__lttng();
155 if (lttng_logger_dentry
)
156 remove_proc_entry("lttng-logger", NULL
);
157 misc_deregister(&logger_dev
);