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 #include <linux/device.h> 74 75 MALLOC_DEFINE(M_DFSINT, "debugfsint", "Linux debugfs internal"); 76 77 static struct pfs_node *debugfs_root; 78 79 #define DM_SYMLINK 0x1 80 #define DM_DIR 0x2 81 #define DM_FILE 0x3 82 83 struct dentry_meta { 84 struct dentry dm_dnode; 85 const struct file_operations *dm_fops; 86 void *dm_data; 87 umode_t dm_mode; 88 int dm_type; 89 }; 90 91 static int 92 debugfs_attr(PFS_ATTR_ARGS) 93 { 94 struct dentry_meta *dm; 95 96 dm = pn->pn_data; 97 98 vap->va_mode = dm->dm_mode; 99 return (0); 100 } 101 102 static int 103 debugfs_destroy(PFS_DESTROY_ARGS) 104 { 105 struct dentry_meta *dm; 106 107 dm = pn->pn_data; 108 if (dm != NULL && dm->dm_type == DM_SYMLINK) 109 free(dm->dm_data, M_DFSINT); 110 111 free(dm, M_DFSINT); 112 return (0); 113 } 114 115 static int 116 debugfs_fill(PFS_FILL_ARGS) 117 { 118 struct dentry_meta *d; 119 struct linux_file lf = {}; 120 struct vnode vn; 121 struct iovec *iov; 122 size_t cnt, orig_resid; 123 ssize_t rc; 124 off_t off; 125 126 /* Linux file operations assume a pointer to a user buffer. */ 127 if (uio->uio_segflg != UIO_USERSPACE) 128 return (EOPNOTSUPP); 129 130 if ((rc = linux_set_current_flags(curthread, M_NOWAIT))) 131 return (rc); 132 133 d = pn->pn_data; 134 vn.v_data = d->dm_data; 135 136 rc = d->dm_fops->open(&vn, &lf); 137 if (rc < 0) { 138 #ifdef INVARIANTS 139 printf("%s:%d open failed with %zd\n", __func__, __LINE__, rc); 140 #endif 141 return (-rc); 142 } 143 144 off = uio->uio_offset; 145 orig_resid = uio->uio_resid; 146 while (uio->uio_resid > 0) { 147 KASSERT(uio->uio_iovcnt > 0, 148 ("%s: uio %p iovcnt underflow", __func__, uio)); 149 150 iov = uio->uio_iov; 151 cnt = iov->iov_len; 152 if (cnt == 0) { 153 uio->uio_iov++; 154 uio->uio_iovcnt--; 155 continue; 156 } 157 if (cnt > uio->uio_resid) 158 cnt = uio->uio_resid; 159 160 switch (uio->uio_rw) { 161 case UIO_READ: 162 if (d->dm_fops->read != NULL) 163 rc = d->dm_fops->read(&lf, iov->iov_base, cnt, 164 &off); 165 else 166 rc = -ENODEV; 167 break; 168 case UIO_WRITE: 169 if (d->dm_fops->write != NULL) 170 rc = d->dm_fops->write(&lf, iov->iov_base, cnt, 171 &off); 172 else 173 rc = -ENODEV; 174 break; 175 } 176 177 if (rc <= 0) 178 break; 179 180 iov->iov_base = (char *)iov->iov_base + rc; 181 iov->iov_len -= rc; 182 uio->uio_resid -= rc; 183 uio->uio_offset = off; 184 } 185 186 if (d->dm_fops->release) 187 d->dm_fops->release(&vn, &lf); 188 189 /* Return success for short operations. */ 190 if (orig_resid != uio->uio_resid) 191 rc = 0; 192 193 if (rc < 0) { 194 #ifdef INVARIANTS 195 printf("%s:%d %s failed with %zd\n", __func__, __LINE__, 196 (uio->uio_rw == UIO_READ) ? "read" : "write", rc); 197 #endif 198 return (-rc); 199 } 200 return (0); 201 } 202 203 static int 204 debugfs_fill_data(PFS_FILL_ARGS) 205 { 206 struct dentry_meta *dm; 207 208 dm = pn->pn_data; 209 sbuf_printf(sb, "%s", (char *)dm->dm_data); 210 return (0); 211 } 212 213 struct dentry * 214 debugfs_create_file(const char *name, umode_t mode, 215 struct dentry *parent, void *data, 216 const struct file_operations *fops) 217 { 218 struct dentry_meta *dm; 219 struct dentry *dnode; 220 struct pfs_node *pnode; 221 int flags; 222 223 dm = malloc(sizeof(*dm), M_DFSINT, M_NOWAIT | M_ZERO); 224 if (dm == NULL) 225 return (NULL); 226 dnode = &dm->dm_dnode; 227 dm->dm_fops = fops; 228 dm->dm_data = data; 229 dm->dm_mode = mode; 230 dm->dm_type = DM_FILE; 231 if (parent != NULL) 232 pnode = parent->d_pfs_node; 233 else 234 pnode = debugfs_root; 235 236 flags = fops->write ? PFS_RDWR : PFS_RD; 237 pfs_create_file(pnode, &dnode->d_pfs_node, name, debugfs_fill, 238 debugfs_attr, NULL, debugfs_destroy, flags | PFS_RAW | PFS_NOWAIT); 239 if (dnode->d_pfs_node == NULL) { 240 free(dm, M_DFSINT); 241 return (NULL); 242 } 243 dnode->d_pfs_node->pn_data = dm; 244 245 return (dnode); 246 } 247 248 struct dentry * 249 debugfs_create_file_size(const char *name, umode_t mode, 250 struct dentry *parent, void *data, 251 const struct file_operations *fops, 252 loff_t file_size __unused) 253 { 254 255 return debugfs_create_file(name, mode, parent, data, fops); 256 } 257 258 /* 259 * NOTE: Files created with the _unsafe moniker will not be protected from 260 * debugfs core file removals. It is the responsibility of @fops to protect 261 * its file using debugfs_file_get() and debugfs_file_put(). 262 * 263 * FreeBSD's LinuxKPI lindebugfs does not perform file removals at the time 264 * of writing. Therefore there is no difference between functions with _unsafe 265 * and functions without _unsafe when using lindebugfs. Functions with _unsafe 266 * exist only for Linux compatibility. 267 */ 268 struct dentry * 269 debugfs_create_file_unsafe(const char *name, umode_t mode, 270 struct dentry *parent, void *data, 271 const struct file_operations *fops) 272 { 273 274 return (debugfs_create_file(name, mode, parent, data, fops)); 275 } 276 277 struct dentry * 278 debugfs_create_mode_unsafe(const char *name, umode_t mode, 279 struct dentry *parent, void *data, 280 const struct file_operations *fops, 281 const struct file_operations *fops_ro, 282 const struct file_operations *fops_wo) 283 { 284 umode_t read = mode & S_IRUGO; 285 umode_t write = mode & S_IWUGO; 286 287 if (read && !write) 288 return (debugfs_create_file_unsafe(name, mode, parent, data, fops_ro)); 289 290 if (write && !read) 291 return (debugfs_create_file_unsafe(name, mode, parent, data, fops_wo)); 292 293 return (debugfs_create_file_unsafe(name, mode, parent, data, fops)); 294 } 295 296 struct dentry * 297 debugfs_create_dir(const char *name, struct dentry *parent) 298 { 299 struct dentry_meta *dm; 300 struct dentry *dnode; 301 struct pfs_node *pnode; 302 303 if (name == NULL) 304 return (NULL); 305 306 dm = malloc(sizeof(*dm), M_DFSINT, M_NOWAIT | M_ZERO); 307 if (dm == NULL) 308 return (NULL); 309 dnode = &dm->dm_dnode; 310 dm->dm_mode = 0700; 311 dm->dm_type = DM_DIR; 312 if (parent != NULL) 313 pnode = parent->d_pfs_node; 314 else 315 pnode = debugfs_root; 316 317 pfs_create_dir(pnode, &dnode->d_pfs_node, name, debugfs_attr, NULL, 318 debugfs_destroy, PFS_RD | PFS_NOWAIT); 319 if (dnode->d_pfs_node == NULL) { 320 free(dm, M_DFSINT); 321 return (NULL); 322 } 323 dnode->d_pfs_node->pn_data = dm; 324 return (dnode); 325 } 326 327 struct dentry * 328 debugfs_create_symlink(const char *name, struct dentry *parent, 329 const char *dest) 330 { 331 struct dentry_meta *dm; 332 struct dentry *dnode; 333 struct pfs_node *pnode; 334 void *data; 335 336 data = strdup_flags(dest, M_DFSINT, M_NOWAIT); 337 if (data == NULL) 338 return (NULL); 339 dm = malloc(sizeof(*dm), M_DFSINT, M_NOWAIT | M_ZERO); 340 if (dm == NULL) 341 goto fail1; 342 dnode = &dm->dm_dnode; 343 dm->dm_mode = 0700; 344 dm->dm_type = DM_SYMLINK; 345 dm->dm_data = data; 346 if (parent != NULL) 347 pnode = parent->d_pfs_node; 348 else 349 pnode = debugfs_root; 350 351 pfs_create_link(pnode, &dnode->d_pfs_node, name, &debugfs_fill_data, 352 NULL, NULL, NULL, PFS_NOWAIT); 353 if (dnode->d_pfs_node == NULL) 354 goto fail; 355 dnode->d_pfs_node->pn_data = dm; 356 return (dnode); 357 fail: 358 free(dm, M_DFSINT); 359 fail1: 360 free(data, M_DFSINT); 361 return (NULL); 362 } 363 364 struct dentry * 365 debugfs_lookup(const char *name, struct dentry *parent) 366 { 367 struct dentry_meta *dm; 368 struct dentry *dnode; 369 struct pfs_node *pnode; 370 371 pnode = pfs_find_node(parent->d_pfs_node, name); 372 if (pnode == NULL) 373 return (NULL); 374 375 dm = (struct dentry_meta *)pnode->pn_data; 376 dnode = &dm->dm_dnode; 377 378 return (dnode); 379 } 380 381 void 382 debugfs_remove(struct dentry *dnode) 383 { 384 if (dnode == NULL) 385 return; 386 387 pfs_destroy(dnode->d_pfs_node); 388 } 389 390 void 391 debugfs_remove_recursive(struct dentry *dnode) 392 { 393 if (dnode == NULL) 394 return; 395 396 pfs_destroy(dnode->d_pfs_node); 397 } 398 399 static int 400 debugfs_bool_get(void *data, uint64_t *ullval) 401 { 402 bool *bval = data; 403 404 if (*bval) 405 *ullval = 1; 406 else 407 *ullval = 0; 408 409 return (0); 410 } 411 412 static int 413 debugfs_bool_set(void *data, uint64_t ullval) 414 { 415 bool *bval = data; 416 417 if (ullval) 418 *bval = 1; 419 else 420 *bval = 0; 421 422 return (0); 423 } 424 425 DEFINE_DEBUGFS_ATTRIBUTE(fops_bool, debugfs_bool_get, debugfs_bool_set, "%llu\n"); 426 DEFINE_DEBUGFS_ATTRIBUTE(fops_bool_ro, debugfs_bool_get, NULL, "%llu\n"); 427 DEFINE_DEBUGFS_ATTRIBUTE(fops_bool_wo, NULL, debugfs_bool_set, "%llu\n"); 428 429 void 430 debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, bool *value) 431 { 432 433 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_bool, 434 &fops_bool_ro, &fops_bool_wo); 435 } 436 437 438 static int 439 debugfs_u8_get(void *data, uint64_t *value) 440 { 441 uint8_t *u8data = data; 442 *value = *u8data; 443 return (0); 444 } 445 446 static int 447 debugfs_u8_set(void *data, uint64_t value) 448 { 449 uint8_t *u8data = data; 450 *u8data = (uint8_t)value; 451 return (0); 452 } 453 454 DEFINE_DEBUGFS_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%u\n"); 455 DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_ro, debugfs_u8_get, NULL, "%u\n"); 456 DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%u\n"); 457 458 void 459 debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, uint8_t *value) 460 { 461 462 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u8, 463 &fops_u8_ro, &fops_u8_wo); 464 } 465 466 DEFINE_DEBUGFS_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%016llx\n"); 467 DEFINE_DEBUGFS_ATTRIBUTE(fops_x8_ro, debugfs_u8_get, NULL, "0x%016llx\n"); 468 DEFINE_DEBUGFS_ATTRIBUTE(fops_x8_wo, NULL, debugfs_u8_set, "0x%016llx\n"); 469 470 void 471 debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, uint8_t *value) 472 { 473 474 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x8, 475 &fops_x8_ro, &fops_x8_wo); 476 } 477 478 479 static int 480 debugfs_u16_get(void *data, uint64_t *value) 481 { 482 uint16_t *u16data = data; 483 *value = *u16data; 484 return (0); 485 } 486 487 static int 488 debugfs_u16_set(void *data, uint64_t value) 489 { 490 uint16_t *u16data = data; 491 *u16data = (uint16_t)value; 492 return (0); 493 } 494 495 DEFINE_DEBUGFS_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%u\n"); 496 DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_ro, debugfs_u16_get, NULL, "%u\n"); 497 DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%u\n"); 498 499 void 500 debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, uint16_t *value) 501 { 502 503 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u16, 504 &fops_u16_ro, &fops_u16_wo); 505 } 506 507 DEFINE_DEBUGFS_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%016llx\n"); 508 DEFINE_DEBUGFS_ATTRIBUTE(fops_x16_ro, debugfs_u16_get, NULL, "0x%016llx\n"); 509 DEFINE_DEBUGFS_ATTRIBUTE(fops_x16_wo, NULL, debugfs_u16_set, "0x%016llx\n"); 510 511 void 512 debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, uint16_t *value) 513 { 514 515 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x16, 516 &fops_x16_ro, &fops_x16_wo); 517 } 518 519 520 static int 521 debugfs_u32_get(void *data, uint64_t *value) 522 { 523 uint32_t *u32data = data; 524 *value = *u32data; 525 return (0); 526 } 527 528 static int 529 debugfs_u32_set(void *data, uint64_t value) 530 { 531 uint32_t *u32data = data; 532 *u32data = (uint32_t)value; 533 return (0); 534 } 535 536 DEFINE_DEBUGFS_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%u\n"); 537 DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_ro, debugfs_u32_get, NULL, "%u\n"); 538 DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%u\n"); 539 540 void 541 debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, uint32_t *value) 542 { 543 544 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u32, 545 &fops_u32_ro, &fops_u32_wo); 546 } 547 548 DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%016llx\n"); 549 DEFINE_DEBUGFS_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%016llx\n"); 550 DEFINE_DEBUGFS_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%016llx\n"); 551 552 void 553 debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, uint32_t *value) 554 { 555 556 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x32, 557 &fops_x32_ro, &fops_x32_wo); 558 } 559 560 561 static int 562 debugfs_u64_get(void *data, uint64_t *value) 563 { 564 uint64_t *u64data = data; 565 *value = *u64data; 566 return (0); 567 } 568 569 static int 570 debugfs_u64_set(void *data, uint64_t value) 571 { 572 uint64_t *u64data = data; 573 *u64data = (uint64_t)value; 574 return (0); 575 } 576 577 DEFINE_DEBUGFS_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%u\n"); 578 DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_ro, debugfs_u64_get, NULL, "%u\n"); 579 DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%u\n"); 580 581 void 582 debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, uint64_t *value) 583 { 584 585 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u64, 586 &fops_u64_ro, &fops_u64_wo); 587 } 588 589 DEFINE_DEBUGFS_ATTRIBUTE(fops_x64, debugfs_u64_get, debugfs_u64_set, "0x%016llx\n"); 590 DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_ro, debugfs_u64_get, NULL, "0x%016llx\n"); 591 DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_wo, NULL, debugfs_u64_set, "0x%016llx\n"); 592 593 void 594 debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, uint64_t *value) 595 { 596 597 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x64, 598 &fops_x64_ro, &fops_x64_wo); 599 } 600 601 602 static int 603 debugfs_ulong_get(void *data, uint64_t *value) 604 { 605 uint64_t *uldata = data; 606 *value = *uldata; 607 return (0); 608 } 609 610 static int 611 debugfs_ulong_set(void *data, uint64_t value) 612 { 613 uint64_t *uldata = data; 614 *uldata = value; 615 return (0); 616 } 617 618 DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong, debugfs_ulong_get, debugfs_ulong_set, "%llu\n"); 619 DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_ro, debugfs_ulong_get, NULL, "%llu\n"); 620 DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n"); 621 622 void 623 debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value) 624 { 625 626 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_ulong, 627 &fops_ulong_ro, &fops_ulong_wo); 628 } 629 630 631 static int 632 debugfs_atomic_t_get(void *data, uint64_t *value) 633 { 634 atomic_t *atomic_data = data; 635 *value = atomic_read(atomic_data); 636 return (0); 637 } 638 639 static int 640 debugfs_atomic_t_set(void *data, uint64_t value) 641 { 642 atomic_t *atomic_data = data; 643 atomic_set(atomic_data, (int)value); 644 return (0); 645 } 646 647 DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get, debugfs_atomic_t_set, "%d\n"); 648 DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, "%d\n"); 649 DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, "%d\n"); 650 651 void 652 debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value) 653 { 654 655 debugfs_create_mode_unsafe(name, mode, parent, value, &fops_atomic_t, 656 &fops_atomic_t_ro, &fops_atomic_t_wo); 657 } 658 659 660 static int 661 fops_str_open(struct inode *inode, struct file *filp) 662 { 663 664 return (simple_open(inode, filp)); 665 } 666 667 static ssize_t 668 fops_str_read(struct file *filp, char __user *ubuf, size_t read_size, 669 loff_t *ppos) 670 { 671 ssize_t ret; 672 char *str, *str_with_newline; 673 size_t str_len, str_with_newline_len; 674 675 if (filp->private_data == NULL) 676 return (-EINVAL); 677 678 str = *(char **)filp->private_data; 679 str_len = strlen(str); 680 681 /* 682 * `str_with_newline` is terminated with a newline, but is not 683 * NUL-terminated. 684 */ 685 str_with_newline_len = str_len + 1; 686 str_with_newline = kmalloc(str_with_newline_len, GFP_KERNEL); 687 if (str_with_newline == NULL) 688 return (-ENOMEM); 689 690 strncpy(str_with_newline, str, str_len); 691 str_with_newline[str_len] = '\n'; 692 693 ret = simple_read_from_buffer(ubuf, read_size, ppos, 694 str_with_newline, str_with_newline_len); 695 696 kfree(str_with_newline); 697 698 return (ret); 699 } 700 701 static ssize_t 702 fops_str_write(struct file *filp, const char __user *buf, size_t write_size, 703 loff_t *ppos) 704 { 705 char *old, *new; 706 size_t old_len, new_len; 707 708 if (filp->private_data == NULL) 709 return (-EINVAL); 710 711 old = *(char **)filp->private_data; 712 new = NULL; 713 714 /* 715 * We enforce concatenation of the newly written value to the existing 716 * value. 717 */ 718 old_len = strlen(old); 719 if (*ppos && *ppos != old_len) 720 return (-EINVAL); 721 722 new_len = old_len + write_size; 723 if (new_len + 1 > PAGE_SIZE) 724 return (-E2BIG); 725 726 new = kmalloc(new_len + 1, GFP_KERNEL); 727 if (new == NULL) 728 return (-ENOMEM); 729 730 memcpy(new, old, old_len); 731 if (copy_from_user(new + old_len, buf, write_size) != 0) { 732 kfree(new); 733 return (-EFAULT); 734 } 735 736 new[new_len] = '\0'; 737 strim(new); 738 739 filp->private_data = &new; 740 741 kfree(old); 742 743 return (write_size); 744 } 745 746 static const struct file_operations fops_str = { 747 .owner = THIS_MODULE, 748 .open = fops_str_open, 749 .read = fops_str_read, 750 .write = fops_str_write, 751 .llseek = no_llseek 752 }; 753 static const struct file_operations fops_str_ro = { 754 .owner = THIS_MODULE, 755 .open = fops_str_open, 756 .read = fops_str_read, 757 .llseek = no_llseek 758 }; 759 static const struct file_operations fops_str_wo = { 760 .owner = THIS_MODULE, 761 .open = fops_str_open, 762 .write = fops_str_write, 763 .llseek = no_llseek 764 }; 765 766 void 767 debugfs_create_str(const char *name, umode_t mode, struct dentry *parent, 768 char **value) 769 { 770 debugfs_create_mode_unsafe(name, mode, parent, value, 771 &fops_str, &fops_str_ro, &fops_str_wo); 772 } 773 774 775 static ssize_t 776 fops_blob_read(struct file *filp, char __user *ubuf, size_t read_size, loff_t *ppos) 777 { 778 struct debugfs_blob_wrapper *blob; 779 780 blob = filp->private_data; 781 if (blob == NULL) 782 return (-EINVAL); 783 if (blob->size == 0 || blob->data == NULL) 784 return (-EINVAL); 785 786 return (simple_read_from_buffer(ubuf, read_size, ppos, blob->data, blob->size)); 787 } 788 789 static int 790 fops_blob_open(struct inode *inode, struct file *filp) 791 { 792 793 return (simple_open(inode, filp)); 794 } 795 796 static const struct file_operations __fops_blob_ro = { 797 .owner = THIS_MODULE, 798 .open = fops_blob_open, 799 .read = fops_blob_read, 800 .llseek = no_llseek 801 }; 802 803 struct dentry * 804 debugfs_create_blob(const char *name, umode_t mode, struct dentry *parent, 805 struct debugfs_blob_wrapper *value) 806 { 807 /* Blobs are read-only. */ 808 return (debugfs_create_file(name, mode & 0444, parent, value, &__fops_blob_ro)); 809 } 810 811 /* ---------------------------------------------------------------------------- */ 812 /* This should be migrated to ??? */ 813 814 struct debugfs_devm_seqfile { 815 struct device *dev; 816 int (*readfunc)(struct seq_file *, void *); 817 }; 818 819 static int 820 debugfs_devm_seqfile_open(struct inode *inode, struct linux_file *f) 821 { 822 struct debugfs_devm_seqfile *s; 823 824 s = inode->i_private; 825 return (single_open(f, s->readfunc, s->dev)); 826 } 827 828 static const struct file_operations debugfs_devm_seqfile_ops = { 829 .owner = THIS_MODULE, 830 .open = debugfs_devm_seqfile_open, 831 .read = seq_read, 832 .llseek = seq_lseek, 833 .release = single_release, 834 }; 835 836 void 837 debugfs_create_devm_seqfile(struct device *dev, const char *name, 838 struct dentry *d, int (*readfunc)(struct seq_file *m, void *arg)) 839 { 840 struct debugfs_devm_seqfile *s; 841 842 s = devm_kzalloc(dev, sizeof(*s), GFP_KERNEL); 843 if (s == NULL) 844 return; 845 846 s->dev = dev; 847 s->readfunc = readfunc; 848 849 debugfs_create_file(name, 0444, d, s, &debugfs_devm_seqfile_ops); 850 } 851 /* ---------------------------------------------------------------------------- */ 852 853 static int 854 lindebugfs_init(PFS_INIT_ARGS) 855 { 856 857 debugfs_root = pi->pi_root; 858 859 (void)debugfs_create_symlink("kcov", NULL, "/dev/kcov"); 860 861 return (0); 862 } 863 864 static int 865 lindebugfs_uninit(PFS_INIT_ARGS) 866 { 867 868 return (0); 869 } 870 871 PSEUDOFS(lindebugfs, 1, VFCF_JAIL); 872 MODULE_DEPEND(lindebugfs, linuxkpi, 1, 1, 1); 873