1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
7 * Copyright (C) 2008-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 #include <linux/module.h>
11 #include <wrapper/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
26 #define TRACE_INCLUDE_FILE lttng
27 #define LTTNG_INSTRUMENTATION
29 #include <instrumentation/events/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 LTTNG_DEFINE_TRACE(lttng_logger
,
36 PARAMS(const char __user
*text
, size_t len
),
40 static struct proc_dir_entry
*lttng_logger_dentry
;
43 * lttng_logger_write - write a userspace string into the trace system
45 * @user_buf: user string
46 * @count: length to copy
47 * @ppos: file position
49 * Copy a userspace string into a trace event named "lttng:logger".
50 * Copies at most @count bytes into the event "msg" dynamic array.
51 * Truncates the count at LTTNG_LOGGER_COUNT_MAX. Returns the number of
52 * bytes copied from the source.
53 * Return -1 on error, with EFAULT errno.
56 ssize_t
lttng_logger_write(struct file
*file
, const char __user
*user_buf
,
57 size_t count
, loff_t
*ppos
)
60 unsigned long uaddr
= (unsigned long) user_buf
;
61 struct page
*pages
[2];
66 if (unlikely(count
> LTTNG_LOGGER_COUNT_MAX
))
67 count
= LTTNG_LOGGER_COUNT_MAX
;
69 /* How many pages are we dealing with ? */
70 if (unlikely((uaddr
& PAGE_MASK
) != ((uaddr
+ count
) & PAGE_MASK
)))
73 /* Pin userspace pages */
74 ret
= get_user_pages_fast(uaddr
, nr_pages
, 0, pages
);
75 if (unlikely(ret
< nr_pages
)) {
85 trace_lttng_logger(user_buf
, count
);
89 for (i
= 0; i
< nr_pages
; i
++)
95 static const struct file_operations lttng_logger_operations
= {
96 .write
= lttng_logger_write
,
100 * Linux 5.6 introduced a separate proc_ops struct for /proc operations
101 * to decouple it from the vfs.
103 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
104 static const struct proc_ops lttng_logger_proc_ops
= {
105 .proc_write
= lttng_logger_write
,
108 #define lttng_logger_proc_ops lttng_logger_operations
111 static struct miscdevice logger_dev
= {
112 .minor
= MISC_DYNAMIC_MINOR
,
113 .name
= "lttng-logger",
115 .fops
= <tng_logger_operations
118 int __init
lttng_logger_init(void)
122 wrapper_vmalloc_sync_mappings();
124 /* /dev/lttng-logger */
125 ret
= misc_register(&logger_dev
);
127 printk(KERN_ERR
"LTTng: Error creating logger device\n");
131 /* /proc/lttng-logger */
132 lttng_logger_dentry
= proc_create_data(LTTNG_LOGGER_FILE
,
133 S_IRUGO
| S_IWUGO
, NULL
,
134 <tng_logger_proc_ops
, NULL
);
135 if (!lttng_logger_dentry
) {
136 printk(KERN_ERR
"LTTng: Error creating logger proc file\n");
142 ret
= __lttng_events_init__lttng();
148 remove_proc_entry("lttng-logger", NULL
);
150 misc_deregister(&logger_dev
);
155 void lttng_logger_exit(void)
157 __lttng_events_exit__lttng();
158 if (lttng_logger_dentry
)
159 remove_proc_entry("lttng-logger", NULL
);
160 misc_deregister(&logger_dev
);