1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * trace_seq.c
4 *
5 * Copyright (C) 2008-2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
6 *
7 * The trace_seq is a handy tool that allows you to pass a descriptor around
8 * to a buffer that other functions can write to. It is similar to the
9 * seq_file functionality but has some differences.
10 *
11 * To use it, the trace_seq must be initialized with trace_seq_init().
12 * This will set up the counters within the descriptor. You can call
13 * trace_seq_init() more than once to reset the trace_seq to start
14 * from scratch.
15 *
16 * A write to the buffer will either succeed or fail. That is, unlike
17 * sprintf() there will not be a partial write (well it may write into
18 * the buffer but it won't update the pointers). This allows users to
19 * try to write something into the trace_seq buffer and if it fails
20 * they can flush it and try again.
21 *
22 */
23 #include <linux/uaccess.h>
24 #include <linux/seq_file.h>
25 #include <linux/trace_seq.h>
26
27 /* How much buffer is left on the trace_seq? */
28 #define TRACE_SEQ_BUF_LEFT(s) seq_buf_buffer_left(&(s)->seq)
29
30 /*
31 * trace_seq should work with being initialized with 0s.
32 */
__trace_seq_init(struct trace_seq * s)33 static inline void __trace_seq_init(struct trace_seq *s)
34 {
35 if (unlikely(!s->seq.size))
36 trace_seq_init(s);
37 }
38
39 /**
40 * trace_print_seq - move the contents of trace_seq into a seq_file
41 * @m: the seq_file descriptor that is the destination
42 * @s: the trace_seq descriptor that is the source.
43 *
44 * Returns 0 on success and non zero on error. If it succeeds to
45 * write to the seq_file it will reset the trace_seq, otherwise
46 * it does not modify the trace_seq to let the caller try again.
47 */
trace_print_seq(struct seq_file * m,struct trace_seq * s)48 int trace_print_seq(struct seq_file *m, struct trace_seq *s)
49 {
50 int ret;
51
52 __trace_seq_init(s);
53
54 ret = seq_buf_print_seq(m, &s->seq);
55
56 /*
57 * Only reset this buffer if we successfully wrote to the
58 * seq_file buffer. This lets the caller try again or
59 * do something else with the contents.
60 */
61 if (!ret)
62 trace_seq_init(s);
63
64 return ret;
65 }
66
67 /**
68 * trace_seq_printf - sequence printing of trace information
69 * @s: trace sequence descriptor
70 * @fmt: printf format string
71 *
72 * The tracer may use either sequence operations or its own
73 * copy to user routines. To simplify formatting of a trace
74 * trace_seq_printf() is used to store strings into a special
75 * buffer (@s). Then the output may be either used by
76 * the sequencer or pulled into another buffer.
77 */
trace_seq_printf(struct trace_seq * s,const char * fmt,...)78 void trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
79 {
80 unsigned int save_len = s->seq.len;
81 va_list ap;
82
83 if (s->full)
84 return;
85
86 __trace_seq_init(s);
87
88 va_start(ap, fmt);
89 seq_buf_vprintf(&s->seq, fmt, ap);
90 va_end(ap);
91
92 /* If we can't write it all, don't bother writing anything */
93 if (unlikely(seq_buf_has_overflowed(&s->seq))) {
94 s->seq.len = save_len;
95 s->full = 1;
96 }
97 }
98 EXPORT_SYMBOL_GPL(trace_seq_printf);
99
100 /**
101 * trace_seq_bitmask - write a bitmask array in its ASCII representation
102 * @s: trace sequence descriptor
103 * @maskp: points to an array of unsigned longs that represent a bitmask
104 * @nmaskbits: The number of bits that are valid in @maskp
105 *
106 * Writes a ASCII representation of a bitmask string into @s.
107 */
trace_seq_bitmask(struct trace_seq * s,const unsigned long * maskp,int nmaskbits)108 void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
109 int nmaskbits)
110 {
111 unsigned int save_len = s->seq.len;
112
113 if (s->full)
114 return;
115
116 __trace_seq_init(s);
117
118 seq_buf_printf(&s->seq, "%*pb", nmaskbits, maskp);
119
120 if (unlikely(seq_buf_has_overflowed(&s->seq))) {
121 s->seq.len = save_len;
122 s->full = 1;
123 }
124 }
125 EXPORT_SYMBOL_GPL(trace_seq_bitmask);
126
127 /**
128 * trace_seq_bitmask_list - write a bitmask array in its list representation
129 * @s: trace sequence descriptor
130 * @maskp: points to an array of unsigned longs that represent a bitmask
131 * @nmaskbits: The number of bits that are valid in @maskp
132 *
133 * Writes a list representation (e.g., 0-3,5-7) of a bitmask string into @s.
134 */
trace_seq_bitmask_list(struct trace_seq * s,const unsigned long * maskp,int nmaskbits)135 void trace_seq_bitmask_list(struct trace_seq *s, const unsigned long *maskp,
136 int nmaskbits)
137 {
138 unsigned int save_len = s->seq.len;
139
140 if (s->full)
141 return;
142
143 __trace_seq_init(s);
144
145 seq_buf_printf(&s->seq, "%*pbl", nmaskbits, maskp);
146
147 if (unlikely(seq_buf_has_overflowed(&s->seq))) {
148 s->seq.len = save_len;
149 s->full = 1;
150 }
151 }
152 EXPORT_SYMBOL_GPL(trace_seq_bitmask_list);
153
154 /**
155 * trace_seq_vprintf - sequence printing of trace information
156 * @s: trace sequence descriptor
157 * @fmt: printf format string
158 * @args: Arguments for the format string
159 *
160 * The tracer may use either sequence operations or its own
161 * copy to user routines. To simplify formatting of a trace
162 * trace_seq_printf is used to store strings into a special
163 * buffer (@s). Then the output may be either used by
164 * the sequencer or pulled into another buffer.
165 */
trace_seq_vprintf(struct trace_seq * s,const char * fmt,va_list args)166 void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
167 {
168 unsigned int save_len = s->seq.len;
169
170 if (s->full)
171 return;
172
173 __trace_seq_init(s);
174
175 seq_buf_vprintf(&s->seq, fmt, args);
176
177 /* If we can't write it all, don't bother writing anything */
178 if (unlikely(seq_buf_has_overflowed(&s->seq))) {
179 s->seq.len = save_len;
180 s->full = 1;
181 }
182 }
183 EXPORT_SYMBOL_GPL(trace_seq_vprintf);
184
185 /**
186 * trace_seq_bprintf - Write the printf string from binary arguments
187 * @s: trace sequence descriptor
188 * @fmt: The format string for the @binary arguments
189 * @binary: The binary arguments for @fmt.
190 *
191 * When recording in a fast path, a printf may be recorded with just
192 * saving the format and the arguments as they were passed to the
193 * function, instead of wasting cycles converting the arguments into
194 * ASCII characters. Instead, the arguments are saved in a 32 bit
195 * word array that is defined by the format string constraints.
196 *
197 * This function will take the format and the binary array and finish
198 * the conversion into the ASCII string within the buffer.
199 */
trace_seq_bprintf(struct trace_seq * s,const char * fmt,const u32 * binary)200 void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
201 {
202 unsigned int save_len = s->seq.len;
203
204 if (s->full)
205 return;
206
207 __trace_seq_init(s);
208
209 seq_buf_bprintf(&s->seq, fmt, binary);
210
211 /* If we can't write it all, don't bother writing anything */
212 if (unlikely(seq_buf_has_overflowed(&s->seq))) {
213 s->seq.len = save_len;
214 s->full = 1;
215 return;
216 }
217 }
218 EXPORT_SYMBOL_GPL(trace_seq_bprintf);
219
220 /**
221 * trace_seq_puts - trace sequence printing of simple string
222 * @s: trace sequence descriptor
223 * @str: simple string to record
224 *
225 * The tracer may use either the sequence operations or its own
226 * copy to user routines. This function records a simple string
227 * into a special buffer (@s) for later retrieval by a sequencer
228 * or other mechanism.
229 */
trace_seq_puts(struct trace_seq * s,const char * str)230 void trace_seq_puts(struct trace_seq *s, const char *str)
231 {
232 unsigned int len = strlen(str);
233
234 if (s->full)
235 return;
236
237 __trace_seq_init(s);
238
239 if (len > TRACE_SEQ_BUF_LEFT(s)) {
240 s->full = 1;
241 return;
242 }
243
244 seq_buf_putmem(&s->seq, str, len);
245 }
246 EXPORT_SYMBOL_GPL(trace_seq_puts);
247
248 /**
249 * trace_seq_putc - trace sequence printing of simple character
250 * @s: trace sequence descriptor
251 * @c: simple character to record
252 *
253 * The tracer may use either the sequence operations or its own
254 * copy to user routines. This function records a simple character
255 * into a special buffer (@s) for later retrieval by a sequencer
256 * or other mechanism.
257 */
trace_seq_putc(struct trace_seq * s,unsigned char c)258 void trace_seq_putc(struct trace_seq *s, unsigned char c)
259 {
260 if (s->full)
261 return;
262
263 __trace_seq_init(s);
264
265 if (TRACE_SEQ_BUF_LEFT(s) < 1) {
266 s->full = 1;
267 return;
268 }
269
270 seq_buf_putc(&s->seq, c);
271 }
272 EXPORT_SYMBOL_GPL(trace_seq_putc);
273
274 /**
275 * trace_seq_putmem - write raw data into the trace_seq buffer
276 * @s: trace sequence descriptor
277 * @mem: The raw memory to copy into the buffer
278 * @len: The length of the raw memory to copy (in bytes)
279 *
280 * There may be cases where raw memory needs to be written into the
281 * buffer and a strcpy() would not work. Using this function allows
282 * for such cases.
283 */
trace_seq_putmem(struct trace_seq * s,const void * mem,unsigned int len)284 void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
285 {
286 if (s->full)
287 return;
288
289 __trace_seq_init(s);
290
291 if (len > TRACE_SEQ_BUF_LEFT(s)) {
292 s->full = 1;
293 return;
294 }
295
296 seq_buf_putmem(&s->seq, mem, len);
297 }
298 EXPORT_SYMBOL_GPL(trace_seq_putmem);
299
300 /**
301 * trace_seq_putmem_hex - write raw memory into the buffer in ASCII hex
302 * @s: trace sequence descriptor
303 * @mem: The raw memory to write its hex ASCII representation of
304 * @len: The length of the raw memory to copy (in bytes)
305 *
306 * This is similar to trace_seq_putmem() except instead of just copying the
307 * raw memory into the buffer it writes its ASCII representation of it
308 * in hex characters.
309 */
trace_seq_putmem_hex(struct trace_seq * s,const void * mem,unsigned int len)310 void trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
311 unsigned int len)
312 {
313 unsigned int save_len = s->seq.len;
314
315 if (s->full)
316 return;
317
318 __trace_seq_init(s);
319
320 /* Each byte is represented by two chars */
321 if (len * 2 > TRACE_SEQ_BUF_LEFT(s)) {
322 s->full = 1;
323 return;
324 }
325
326 /* The added spaces can still cause an overflow */
327 seq_buf_putmem_hex(&s->seq, mem, len);
328
329 if (unlikely(seq_buf_has_overflowed(&s->seq))) {
330 s->seq.len = save_len;
331 s->full = 1;
332 return;
333 }
334 }
335 EXPORT_SYMBOL_GPL(trace_seq_putmem_hex);
336
337 /**
338 * trace_seq_path - copy a path into the sequence buffer
339 * @s: trace sequence descriptor
340 * @path: path to write into the sequence buffer.
341 *
342 * Write a path name into the sequence buffer.
343 *
344 * Returns 1 if we successfully written all the contents to
345 * the buffer.
346 * Returns 0 if we the length to write is bigger than the
347 * reserved buffer space. In this case, nothing gets written.
348 */
trace_seq_path(struct trace_seq * s,const struct path * path)349 int trace_seq_path(struct trace_seq *s, const struct path *path)
350 {
351 unsigned int save_len = s->seq.len;
352
353 if (s->full)
354 return 0;
355
356 __trace_seq_init(s);
357
358 if (TRACE_SEQ_BUF_LEFT(s) < 1) {
359 s->full = 1;
360 return 0;
361 }
362
363 seq_buf_path(&s->seq, path, "\n");
364
365 if (unlikely(seq_buf_has_overflowed(&s->seq))) {
366 s->seq.len = save_len;
367 s->full = 1;
368 return 0;
369 }
370
371 return 1;
372 }
373 EXPORT_SYMBOL_GPL(trace_seq_path);
374
375 /**
376 * trace_seq_to_user - copy the sequence buffer to user space
377 * @s: trace sequence descriptor
378 * @ubuf: The userspace memory location to copy to
379 * @cnt: The amount to copy
380 *
381 * Copies the sequence buffer into the userspace memory pointed to
382 * by @ubuf. It starts from the last read position (@s->readpos)
383 * and writes up to @cnt characters or till it reaches the end of
384 * the content in the buffer (@s->len), which ever comes first.
385 *
386 * On success, it returns a positive number of the number of bytes
387 * it copied.
388 *
389 * On failure it returns -EBUSY if all of the content in the
390 * sequence has been already read, which includes nothing in the
391 * sequence (@s->len == @s->readpos).
392 *
393 * Returns -EFAULT if the copy to userspace fails.
394 */
trace_seq_to_user(struct trace_seq * s,char __user * ubuf,int cnt)395 int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt)
396 {
397 int ret;
398 __trace_seq_init(s);
399 ret = seq_buf_to_user(&s->seq, ubuf, s->readpos, cnt);
400 if (ret > 0)
401 s->readpos += ret;
402 return ret;
403 }
404 EXPORT_SYMBOL_GPL(trace_seq_to_user);
405
trace_seq_hex_dump(struct trace_seq * s,const char * prefix_str,int prefix_type,int rowsize,int groupsize,const void * buf,size_t len,bool ascii)406 int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str,
407 int prefix_type, int rowsize, int groupsize,
408 const void *buf, size_t len, bool ascii)
409 {
410 unsigned int save_len = s->seq.len;
411
412 if (s->full)
413 return 0;
414
415 __trace_seq_init(s);
416
417 if (TRACE_SEQ_BUF_LEFT(s) < 1) {
418 s->full = 1;
419 return 0;
420 }
421
422 seq_buf_hex_dump(&(s->seq), prefix_str,
423 prefix_type, rowsize, groupsize,
424 buf, len, ascii);
425
426 if (unlikely(seq_buf_has_overflowed(&s->seq))) {
427 s->seq.len = save_len;
428 s->full = 1;
429 return 0;
430 }
431
432 return 1;
433 }
434 EXPORT_SYMBOL(trace_seq_hex_dump);
435
436 /*
437 * trace_seq_acquire - acquire seq buffer with size len
438 * @s: trace sequence descriptor
439 * @len: size of buffer to be acquired
440 *
441 * acquire buffer with size of @len from trace_seq for output usage,
442 * user can fill string into that buffer.
443 *
444 * Returns start address of acquired buffer.
445 *
446 * it allow multiple usage in one trace output function call.
447 */
trace_seq_acquire(struct trace_seq * s,unsigned int len)448 char *trace_seq_acquire(struct trace_seq *s, unsigned int len)
449 {
450 char *ret = trace_seq_buffer_ptr(s);
451
452 if (!WARN_ON_ONCE(seq_buf_buffer_left(&s->seq) < len))
453 seq_buf_commit(&s->seq, len);
454
455 return ret;
456 }
457 EXPORT_SYMBOL(trace_seq_acquire);
458