1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2016-2018, Matthew Macy <mmacy@freebsd.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/queue.h> 32 #include <sys/blist.h> 33 #include <sys/conf.h> 34 #include <sys/exec.h> 35 #include <sys/filedesc.h> 36 #include <sys/kernel.h> 37 #include <sys/linker.h> 38 #include <sys/malloc.h> 39 #include <sys/mount.h> 40 #include <sys/mutex.h> 41 #include <sys/proc.h> 42 #include <sys/resourcevar.h> 43 #include <sys/sbuf.h> 44 #include <sys/smp.h> 45 #include <sys/socket.h> 46 #include <sys/vnode.h> 47 #include <sys/bus.h> 48 #include <sys/pciio.h> 49 50 #include <dev/pci/pcivar.h> 51 #include <dev/pci/pcireg.h> 52 53 #include <net/if.h> 54 55 #include <vm/vm.h> 56 #include <vm/pmap.h> 57 #include <vm/vm_map.h> 58 #include <vm/vm_param.h> 59 #include <vm/vm_object.h> 60 #include <vm/swap_pager.h> 61 62 #include <machine/bus.h> 63 64 #include <compat/linux/linux_ioctl.h> 65 #include <compat/linux/linux_mib.h> 66 #include <compat/linux/linux_util.h> 67 #include <fs/pseudofs/pseudofs.h> 68 69 #include <asm/atomic.h> 70 #include <linux/compat.h> 71 #include <linux/debugfs.h> 72 #include <linux/fs.h> 73 74 MALLOC_DEFINE(M_DFSINT, "debugfsint", "Linux debugfs internal"); 75 76 static struct pfs_node *debugfs_root; 77 78 #define DM_SYMLINK 0x1 79 #define DM_DIR 0x2 80 #define DM_FILE 0x3 81 82 struct dentry_meta { 83 struct dentry dm_dnode; 84 const struct file_operations *dm_fops; 85 void *dm_data; 86 umode_t dm_mode; 87 int dm_type; 88 }; 89 90 static int 91 debugfs_attr(PFS_ATTR_ARGS) 92 { 93 struct dentry_meta *dm; 94 95 dm = pn->pn_data; 96 97 vap->va_mode = dm->dm_mode; 98 return (0); 99 } 100 101 static int 102 debugfs_destroy(PFS_DESTROY_ARGS) 103 { 104 struct dentry_meta *dm; 105 106 dm = pn->pn_data; 107 if (dm != NULL && dm->dm_type == DM_SYMLINK) 108 free(dm->dm_data, M_DFSINT); 109 110 free(dm, M_DFSINT); 111 return (0); 112 } 113 114 static int 115 debugfs_fill(PFS_FILL_ARGS) 116 { 117 struct dentry_meta *d; 118 struct linux_file lf = {}; 119 struct vnode vn; 120 struct iovec *iov; 121 size_t cnt, orig_resid; 122 ssize_t rc; 123 off_t off; 124 125 /* Linux file operations assume a pointer to a user buffer. */ 126 if (uio->uio_segflg != UIO_USERSPACE) 127 return (EOPNOTSUPP); 128 129 if ((rc = linux_set_current_flags(curthread, M_NOWAIT))) 130 return (rc); 131 132 d = pn->pn_data; 133 vn.v_data = d->dm_data; 134 135 rc = d->dm_fops->open(&vn, &lf); 136 if (rc < 0) { 137 #ifdef INVARIANTS 138 printf("%s:%d open failed with %zd\n", __func__, __LINE__, rc); 139 #endif 140 return (-rc); 141 } 142 143 off = uio->uio_offset; 144 orig_resid = uio->uio_resid; 145 while (uio->uio_resid > 0) { 146 KASSERT(uio->uio_iovcnt > 0, 147 ("%s: uio %p iovcnt underflow", __func__, uio)); 148 149 iov = uio->uio_iov; 150 cnt = iov->iov_len; 151 if (cnt == 0) { 152 uio->uio_iov++; 153 uio->uio_iovcnt--; 154 continue; 155 } 156 if (cnt > uio->uio_resid) 157 cnt = uio->uio_resid; 158 159 switch (uio->uio_rw) { 160 case UIO_READ: 161 if (d->dm_fops->read != NULL) 162 rc = d->dm_fops->read(&lf, iov->iov_base, cnt, 163 &off); 164 else 165 rc = -ENODEV; 166 break; 167 case UIO_WRITE: 168 if (d->dm_fops->write != NULL) 169 rc = d->dm_fops->write(&lf, iov->iov_base, cnt, 170 &off); 171 else 172 rc = -ENODEV; 173 break; 174 } 175 176 if (rc <= 0) 177 break; 178 179 iov->iov_base = (char *)iov->iov_base + rc; 180 iov->iov_len -= rc; 181 uio->uio_resid -= rc; 182 uio->uio_offset = off; 183 } 184 185 if (d->dm_fops->release) 186 d->dm_fops->release(&vn, &lf); 187 188 /* Return success for short operations. */ 189 if (orig_resid != uio->uio_resid) 190 rc = 0; 191 192 if (rc < 0) { 193 #ifdef INVARIANTS 194 printf("%s:%d %s failed with %zd\n", __func__, __LINE__, 195 (uio->uio_rw == UIO_READ) ? "read" : "write", rc); 196 #endif 197 return (-rc); 198 } 199 return (0); 200 } 201 202 static int 203 debugfs_fill_data(PFS_FILL_ARGS) 204 { 205 struct dentry_meta *dm; 206 207 dm = pn->pn_data; 208 sbuf_printf(sb, "%s", (char *)dm->dm_data); 209 return (0); 210 } 211 212 struct dentry * 213 debugfs_create_file(const char *name, umode_t mode, 214 struct dentry *parent, void *data, 215 const struct file_operations *fops) 216 { 217 struct dentry_meta *dm; 218 struct dentry *dnode; 219 struct pfs_node *pnode; 220 int flags; 221 222 dm = malloc(sizeof(*dm), M_DFSINT, M_NOWAIT | M_ZERO); 223 if (dm == NULL) 224 return (NULL); 225 dnode = &dm->dm_dnode; 226 dm->dm_fops = fops; 227 dm->dm_data = data; 228 dm->dm_mode = mode; 229 dm->dm_type = DM_FILE; 230 if (parent != NULL) 231 pnode = parent->d_pfs_node; 232 else 233 pnode = debugfs_root; 234 235 flags = fops->write ? PFS_RDWR : PFS_RD; 236 pfs_create_file(pnode, &dnode->d_pfs_node, name, debugfs_fill, 237 debugfs_attr, NULL, debugfs_destroy, flags | PFS_RAW | PFS_NOWAIT); 238 if (dnode->d_pfs_node == NULL) { 239 free(dm, M_DFSINT); 240 return (NULL); 241 } 242 dnode->d_pfs_node->pn_data = dm; 243 244 return (dnode); 245 } 246 247 struct dentry * 248 debugfs_create_file_size(const char *name, umode_t mode, 249 struct dentry *parent, void *data, 250 const struct file_operations *fops, 251 loff_t file_size __unused) 252 { 253 254 return debugfs_create_file(name, mode, parent, data, fops); 255 } 256 257 /* 258 * NOTE: Files created with the _unsafe moniker will not be protected from 259 * debugfs core file removals. It is the responsibility of @fops to protect 260 * its file using debugfs_file_get() and debugfs_file_put(). 261 * 262 * FreeBSD's LinuxKPI lindebugfs does not perform file removals at the time 263 * of writing. Therefore there is no difference between functions with _unsafe 264 * and functions without _unsafe when using lindebugfs. Functions with _unsafe 265 * exist only for Linux compatibility. 266 */ 267 struct dentry * 268 debugfs_create_file_unsafe(const char *name, umode_t mode, 269 struct dentry *parent, void *data, 270 const struct file_operations *fops) 271 { 272 273 return (debugfs_create_file(name, mode, parent, data, fops)); 274 } 275 276 struct dentry * 277 debugfs_create_mode_unsafe(const char *name, umode_t mode, 278 struct dentry *parent, void *data, 279 const struct file_operations *fops, 280 const struct file_operations *fops_ro, 281 const struct file_operations *fops_wo) 282 { 283 umode_t read = mode & S_IRUGO; 284 umode_t write = mode & S_IWUGO; 285 286 if (read && !write) 287 return (debugfs_create_file_unsafe(name, mode, parent, data, fops_ro)); 288 289 if (write && !read) 290 return (debugfs_create_file_unsafe(name, mode, parent, data, fops_wo)); 291 292 return (debugfs_create_file_unsafe(name, mode, parent, data, fops)); 293 } 294 295 struct dentry * 296 debugfs_create_dir(const char *name, struct dentry *parent) 297 { 298 struct dentry_meta *dm; 299 struct dentry *dnode; 300 struct pfs_node *pnode; 301 302 if (name == NULL) 303 return (NULL); 304 305 dm = malloc(sizeof(*dm), M_DFSINT, M_NOWAIT | M_ZERO); 306 if (dm == NULL) 307 return (NULL); 308 dnode = &dm->dm_dnode; 309 dm->dm_mode = 0700; 310 dm->dm_type = DM_DIR; 311 if (parent != NULL) 312 pnode = parent->d_pfs_node; 313 else 314 pnode = debugfs_root; 315 316 pfs_create_dir(pnode, &dnode->d_pfs_node, name, debugfs_attr, NULL, 317 debugfs_destroy, PFS_RD | PFS_NOWAIT); 318 if (dnode->d_pfs_node == NULL) { 319 free(dm, M_DFSINT); 320 return (NULL); 321 } 322 dnode->d_pfs_node->pn_data = dm; 323 return (dnode); 324 } 325 326 struct dentry * 327 debugfs_create_symlink(const char *name, struct dentry *parent, 328 const char *dest) 329 { 330 struct dentry_meta *dm; 331 struct dentry *dnode; 332 struct pfs_node *pnode; 333 void *data; 334 335 data = strdup_flags(dest, M_DFSINT, M_NOWAIT); 336 if (data == NULL) 337 return (NULL); 338 dm = malloc(sizeof(*dm), M_DFSINT, M_NOWAIT | M_ZERO); 339 if (dm == NULL) 340 goto fail1; 341 dnode = &dm->dm_dnode; 342 dm->dm_mode = 0700; 343 dm->dm_type = DM_SYMLINK; 344 dm->dm_data = data; 345 if (parent != NULL) 346 pnode = parent->d_pfs_node; 347 else 348 pnode = debugfs_root; 349 350 pfs_create_link(pnode, &dnode->d_pfs_node, name, &debugfs_fill_data, 351 NULL, NULL, NULL, PFS_NOWAIT); 352 if (dnode->d_pfs_node == NULL) 353 goto fail; 354 dnode->d_pfs_node->pn_data = dm; 355 return (dnode); 356 fail: 357 free(dm, M_DFSINT); 358 fail1: 359 free(data, M_DFSINT); 360 return (NULL); 361 } 362 363 struct dentry * 364 debugfs_lookup(const char *name, struct dentry *parent) 365 { 366 struct dentry_meta *dm; 367 struct dentry *dnode; 368 struct pfs_node *pnode; 369 370 pnode = pfs_find_node(parent->d_pfs_node, name); 371 if (pnode == NULL) 372 return (NULL); 373 374 dm = (struct dentry_meta *)pnode->pn_data; 375 dnode = &dm->dm_dnode; 376 377 return (dnode); 378 } 379 380 void 381 debugfs_remove(struct dentry *dnode) 382 { 383 if (dnode == NULL) 384 return; 385 386 pfs_destroy(dnode->d_pfs_node); 387 } 388 389 void 390 debugfs_remove_recursive(struct dentry *dnode) 391 { 392 if (dnode == NULL) 393 return; 394 395 pfs_destroy(dnode->d_pfs_node); 396 } 397 398 static int 399 debugfs_bool_get(void *data, uint64_t *ullval) 400 { 401 bool *bval = data; 402 403 if (*bval) 404 *ullval = 1; 405 else 406 *ullval = 0; 407 408 return (0); 409 } 410 411 static int 412 debugfs_bool_set(void *data, uint64_t ullval) 413 { 414 bool *bval = data; 415 416 if (ullval) 417 *bval = 1; 418 else 419 *bval = 0; 420 421 return (0); 422 } 423 424 DEFINE_DEBUGFS_ATTRIBUTE(fops_bool, debugfs_bool_get, debugfs_bool_set, "%llu\n"); 425 DEFINE_DEBUGFS_ATTRIBUTE(fops_bool_ro, debugfs_bool_get, NULL, "%llu\n"); 426 DEFINE_DEBUGFS_ATTRIBUTE(fops_bool_wo, NULL, debugfs_bool_set, "%llu\n"); 427 428 void 429 debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, bool *value) 430 { 431 432 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_bool, 433 &fops_bool_ro, &fops_bool_wo); 434 } 435 436 437 static int 438 debugfs_u8_get(void *data, uint64_t *value) 439 { 440 uint8_t *u8data = data; 441 *value = *u8data; 442 return (0); 443 } 444 445 static int 446 debugfs_u8_set(void *data, uint64_t value) 447 { 448 uint8_t *u8data = data; 449 *u8data = (uint8_t)value; 450 return (0); 451 } 452 453 DEFINE_DEBUGFS_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%u\n"); 454 DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_ro, debugfs_u8_get, NULL, "%u\n"); 455 DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%u\n"); 456 457 void 458 debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, uint8_t *value) 459 { 460 461 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u8, 462 &fops_u8_ro, &fops_u8_wo); 463 } 464 465 DEFINE_DEBUGFS_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%016llx\n"); 466 DEFINE_DEBUGFS_ATTRIBUTE(fops_x8_ro, debugfs_u8_get, NULL, "0x%016llx\n"); 467 DEFINE_DEBUGFS_ATTRIBUTE(fops_x8_wo, NULL, debugfs_u8_set, "0x%016llx\n"); 468 469 void 470 debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, uint8_t *value) 471 { 472 473 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x8, 474 &fops_x8_ro, &fops_x8_wo); 475 } 476 477 478 static int 479 debugfs_u16_get(void *data, uint64_t *value) 480 { 481 uint16_t *u16data = data; 482 *value = *u16data; 483 return (0); 484 } 485 486 static int 487 debugfs_u16_set(void *data, uint64_t value) 488 { 489 uint16_t *u16data = data; 490 *u16data = (uint16_t)value; 491 return (0); 492 } 493 494 DEFINE_DEBUGFS_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%u\n"); 495 DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_ro, debugfs_u16_get, NULL, "%u\n"); 496 DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%u\n"); 497 498 void 499 debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, uint16_t *value) 500 { 501 502 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u16, 503 &fops_u16_ro, &fops_u16_wo); 504 } 505 506 DEFINE_DEBUGFS_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%016llx\n"); 507 DEFINE_DEBUGFS_ATTRIBUTE(fops_x16_ro, debugfs_u16_get, NULL, "0x%016llx\n"); 508 DEFINE_DEBUGFS_ATTRIBUTE(fops_x16_wo, NULL, debugfs_u16_set, "0x%016llx\n"); 509 510 void 511 debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, uint16_t *value) 512 { 513 514 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x16, 515 &fops_x16_ro, &fops_x16_wo); 516 } 517 518 519 static int 520 debugfs_u32_get(void *data, uint64_t *value) 521 { 522 uint32_t *u32data = data; 523 *value = *u32data; 524 return (0); 525 } 526 527 static int 528 debugfs_u32_set(void *data, uint64_t value) 529 { 530 uint32_t *u32data = data; 531 *u32data = (uint32_t)value; 532 return (0); 533 } 534 535 DEFINE_DEBUGFS_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%u\n"); 536 DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_ro, debugfs_u32_get, NULL, "%u\n"); 537 DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%u\n"); 538 539 void 540 debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, uint32_t *value) 541 { 542 543 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u32, 544 &fops_u32_ro, &fops_u32_wo); 545 } 546 547 DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%016llx\n"); 548 DEFINE_DEBUGFS_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%016llx\n"); 549 DEFINE_DEBUGFS_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%016llx\n"); 550 551 void 552 debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, uint32_t *value) 553 { 554 555 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x32, 556 &fops_x32_ro, &fops_x32_wo); 557 } 558 559 560 static int 561 debugfs_u64_get(void *data, uint64_t *value) 562 { 563 uint64_t *u64data = data; 564 *value = *u64data; 565 return (0); 566 } 567 568 static int 569 debugfs_u64_set(void *data, uint64_t value) 570 { 571 uint64_t *u64data = data; 572 *u64data = (uint64_t)value; 573 return (0); 574 } 575 576 DEFINE_DEBUGFS_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%u\n"); 577 DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_ro, debugfs_u64_get, NULL, "%u\n"); 578 DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%u\n"); 579 580 void 581 debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, uint64_t *value) 582 { 583 584 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u64, 585 &fops_u64_ro, &fops_u64_wo); 586 } 587 588 DEFINE_DEBUGFS_ATTRIBUTE(fops_x64, debugfs_u64_get, debugfs_u64_set, "0x%016llx\n"); 589 DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_ro, debugfs_u64_get, NULL, "0x%016llx\n"); 590 DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_wo, NULL, debugfs_u64_set, "0x%016llx\n"); 591 592 void 593 debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, uint64_t *value) 594 { 595 596 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x64, 597 &fops_x64_ro, &fops_x64_wo); 598 } 599 600 601 static int 602 debugfs_ulong_get(void *data, uint64_t *value) 603 { 604 uint64_t *uldata = data; 605 *value = *uldata; 606 return (0); 607 } 608 609 static int 610 debugfs_ulong_set(void *data, uint64_t value) 611 { 612 uint64_t *uldata = data; 613 *uldata = value; 614 return (0); 615 } 616 617 DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong, debugfs_ulong_get, debugfs_ulong_set, "%llu\n"); 618 DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_ro, debugfs_ulong_get, NULL, "%llu\n"); 619 DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n"); 620 621 void 622 debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value) 623 { 624 625 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_ulong, 626 &fops_ulong_ro, &fops_ulong_wo); 627 } 628 629 630 static int 631 debugfs_atomic_t_get(void *data, uint64_t *value) 632 { 633 atomic_t *atomic_data = data; 634 *value = atomic_read(atomic_data); 635 return (0); 636 } 637 638 static int 639 debugfs_atomic_t_set(void *data, uint64_t value) 640 { 641 atomic_t *atomic_data = data; 642 atomic_set(atomic_data, (int)value); 643 return (0); 644 } 645 646 DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get, debugfs_atomic_t_set, "%d\n"); 647 DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, "%d\n"); 648 DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, "%d\n"); 649 650 void 651 debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value) 652 { 653 654 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_atomic_t, 655 &fops_atomic_t_ro, &fops_atomic_t_wo); 656 } 657 658 659 static int 660 fops_str_open(struct inode *inode, struct file *filp) 661 { 662 663 return (simple_open(inode, filp)); 664 } 665 666 static ssize_t 667 fops_str_read(struct file *filp, char __user *ubuf, size_t read_size, 668 loff_t *ppos) 669 { 670 ssize_t ret; 671 char *str, *str_with_newline; 672 size_t str_len, str_with_newline_len; 673 674 if (filp->private_data == NULL) 675 return (-EINVAL); 676 677 str = *(char **)filp->private_data; 678 str_len = strlen(str); 679 680 /* 681 * `str_with_newline` is terminated with a newline, but is not 682 * NUL-terminated. 683 */ 684 str_with_newline_len = str_len + 1; 685 str_with_newline = kmalloc(str_with_newline_len, GFP_KERNEL); 686 if (str_with_newline == NULL) 687 return (-ENOMEM); 688 689 strncpy(str_with_newline, str, str_len); 690 str_with_newline[str_len] = '\n'; 691 692 ret = simple_read_from_buffer(ubuf, read_size, ppos, 693 str_with_newline, str_with_newline_len); 694 695 kfree(str_with_newline); 696 697 return (ret); 698 } 699 700 static ssize_t 701 fops_str_write(struct file *filp, const char __user *buf, size_t write_size, 702 loff_t *ppos) 703 { 704 char *old, *new; 705 size_t old_len, new_len; 706 707 if (filp->private_data == NULL) 708 return (-EINVAL); 709 710 old = *(char **)filp->private_data; 711 new = NULL; 712 713 /* 714 * We enforce concatenation of the newly written value to the existing 715 * value. 716 */ 717 old_len = strlen(old); 718 if (*ppos && *ppos != old_len) 719 return (-EINVAL); 720 721 new_len = old_len + write_size; 722 if (new_len + 1 > PAGE_SIZE) 723 return (-E2BIG); 724 725 new = kmalloc(new_len + 1, GFP_KERNEL); 726 if (new == NULL) 727 return (-ENOMEM); 728 729 memcpy(new, old, old_len); 730 if (copy_from_user(new + old_len, buf, write_size) != 0) { 731 kfree(new); 732 return (-EFAULT); 733 } 734 735 new[new_len] = '\0'; 736 strim(new); 737 738 filp->private_data = &new; 739 740 kfree(old); 741 742 return (write_size); 743 } 744 745 static const struct file_operations fops_str = { 746 .owner = THIS_MODULE, 747 .open = fops_str_open, 748 .read = fops_str_read, 749 .write = fops_str_write, 750 .llseek = no_llseek 751 }; 752 static const struct file_operations fops_str_ro = { 753 .owner = THIS_MODULE, 754 .open = fops_str_open, 755 .read = fops_str_read, 756 .llseek = no_llseek 757 }; 758 static const struct file_operations fops_str_wo = { 759 .owner = THIS_MODULE, 760 .open = fops_str_open, 761 .write = fops_str_write, 762 .llseek = no_llseek 763 }; 764 765 void 766 debugfs_create_str(const char *name, umode_t mode, struct dentry *parent, 767 char **value) 768 { 769 debugfs_create_mode_unsafe(name, mode, parent, value, 770 &fops_str, &fops_str_ro, &fops_str_wo); 771 } 772 773 774 static ssize_t 775 fops_blob_read(struct file *filp, char __user *ubuf, size_t read_size, loff_t *ppos) 776 { 777 struct debugfs_blob_wrapper *blob; 778 779 blob = filp->private_data; 780 if (blob == NULL) 781 return (-EINVAL); 782 if (blob->size == 0 || blob->data == NULL) 783 return (-EINVAL); 784 785 return (simple_read_from_buffer(ubuf, read_size, ppos, blob->data, blob->size)); 786 } 787 788 static int 789 fops_blob_open(struct inode *inode, struct file *filp) 790 { 791 792 return (simple_open(inode, filp)); 793 } 794 795 static const struct file_operations __fops_blob_ro = { 796 .owner = THIS_MODULE, 797 .open = fops_blob_open, 798 .read = fops_blob_read, 799 .llseek = no_llseek 800 }; 801 802 struct dentry * 803 debugfs_create_blob(const char *name, umode_t mode, struct dentry *parent, 804 struct debugfs_blob_wrapper *value) 805 { 806 /* Blobs are read-only. */ 807 return (debugfs_create_file(name, mode & 0444, parent, value, &__fops_blob_ro)); 808 } 809 810 811 static int 812 lindebugfs_init(PFS_INIT_ARGS) 813 { 814 815 debugfs_root = pi->pi_root; 816 817 (void)debugfs_create_symlink("kcov", NULL, "/dev/kcov"); 818 819 return (0); 820 } 821 822 static int 823 lindebugfs_uninit(PFS_INIT_ARGS) 824 { 825 826 return (0); 827 } 828 829 PSEUDOFS(lindebugfs, 1, VFCF_JAIL); 830 MODULE_DEPEND(lindebugfs, linuxkpi, 1, 1, 1); 831