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