| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * SPU file system -- file contents |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Arnd Bergmann <arndb@de.ibm.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2, or (at your option) |
|---|
| 11 | | - * any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | | - * You should have received a copy of the GNU General Public License |
|---|
| 19 | | - * along with this program; if not, write to the Free Software |
|---|
| 20 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 21 | 8 | */ |
|---|
| 22 | 9 | |
|---|
| 23 | 10 | #undef DEBUG |
|---|
| 24 | 11 | |
|---|
| 12 | +#include <linux/coredump.h> |
|---|
| 25 | 13 | #include <linux/fs.h> |
|---|
| 26 | 14 | #include <linux/ioctl.h> |
|---|
| 27 | 15 | #include <linux/export.h> |
|---|
| .. | .. |
|---|
| 142 | 130 | return ret; |
|---|
| 143 | 131 | } |
|---|
| 144 | 132 | |
|---|
| 133 | +static ssize_t spufs_dump_emit(struct coredump_params *cprm, void *buf, |
|---|
| 134 | + size_t size) |
|---|
| 135 | +{ |
|---|
| 136 | + if (!dump_emit(cprm, buf, size)) |
|---|
| 137 | + return -EIO; |
|---|
| 138 | + return size; |
|---|
| 139 | +} |
|---|
| 140 | + |
|---|
| 145 | 141 | #define DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \ |
|---|
| 146 | 142 | static int __fops ## _open(struct inode *inode, struct file *file) \ |
|---|
| 147 | 143 | { \ |
|---|
| .. | .. |
|---|
| 185 | 181 | } |
|---|
| 186 | 182 | |
|---|
| 187 | 183 | static ssize_t |
|---|
| 188 | | -__spufs_mem_read(struct spu_context *ctx, char __user *buffer, |
|---|
| 189 | | - size_t size, loff_t *pos) |
|---|
| 184 | +spufs_mem_dump(struct spu_context *ctx, struct coredump_params *cprm) |
|---|
| 190 | 185 | { |
|---|
| 191 | | - char *local_store = ctx->ops->get_ls(ctx); |
|---|
| 192 | | - return simple_read_from_buffer(buffer, size, pos, local_store, |
|---|
| 193 | | - LS_SIZE); |
|---|
| 186 | + return spufs_dump_emit(cprm, ctx->ops->get_ls(ctx), LS_SIZE); |
|---|
| 194 | 187 | } |
|---|
| 195 | 188 | |
|---|
| 196 | 189 | static ssize_t |
|---|
| .. | .. |
|---|
| 203 | 196 | ret = spu_acquire(ctx); |
|---|
| 204 | 197 | if (ret) |
|---|
| 205 | 198 | return ret; |
|---|
| 206 | | - ret = __spufs_mem_read(ctx, buffer, size, pos); |
|---|
| 199 | + ret = simple_read_from_buffer(buffer, size, pos, ctx->ops->get_ls(ctx), |
|---|
| 200 | + LS_SIZE); |
|---|
| 207 | 201 | spu_release(ctx); |
|---|
| 208 | 202 | |
|---|
| 209 | 203 | return ret; |
|---|
| .. | .. |
|---|
| 331 | 325 | return VM_FAULT_SIGBUS; |
|---|
| 332 | 326 | |
|---|
| 333 | 327 | /* |
|---|
| 334 | | - * Because we release the mmap_sem, the context may be destroyed while |
|---|
| 328 | + * Because we release the mmap_lock, the context may be destroyed while |
|---|
| 335 | 329 | * we're in spu_wait. Grab an extra reference so it isn't destroyed |
|---|
| 336 | 330 | * in the meantime. |
|---|
| 337 | 331 | */ |
|---|
| .. | .. |
|---|
| 340 | 334 | /* |
|---|
| 341 | 335 | * We have to wait for context to be loaded before we have |
|---|
| 342 | 336 | * pages to hand out to the user, but we don't want to wait |
|---|
| 343 | | - * with the mmap_sem held. |
|---|
| 344 | | - * It is possible to drop the mmap_sem here, but then we need |
|---|
| 337 | + * with the mmap_lock held. |
|---|
| 338 | + * It is possible to drop the mmap_lock here, but then we need |
|---|
| 345 | 339 | * to return VM_FAULT_NOPAGE because the mappings may have |
|---|
| 346 | 340 | * hanged. |
|---|
| 347 | 341 | */ |
|---|
| .. | .. |
|---|
| 349 | 343 | goto refault; |
|---|
| 350 | 344 | |
|---|
| 351 | 345 | if (ctx->state == SPU_STATE_SAVED) { |
|---|
| 352 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 346 | + mmap_read_unlock(current->mm); |
|---|
| 353 | 347 | spu_context_nospu_trace(spufs_ps_fault__sleep, ctx); |
|---|
| 354 | 348 | err = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); |
|---|
| 355 | 349 | spu_context_trace(spufs_ps_fault__wake, ctx, ctx->spu); |
|---|
| 356 | | - down_read(¤t->mm->mmap_sem); |
|---|
| 350 | + mmap_read_lock(current->mm); |
|---|
| 357 | 351 | } else { |
|---|
| 358 | 352 | area = ctx->spu->problem_phys + ps_offs; |
|---|
| 359 | 353 | ret = vmf_insert_pfn(vmf->vma, vmf->address, |
|---|
| .. | .. |
|---|
| 459 | 453 | .release = spufs_cntl_release, |
|---|
| 460 | 454 | .read = simple_attr_read, |
|---|
| 461 | 455 | .write = simple_attr_write, |
|---|
| 462 | | - .llseek = generic_file_llseek, |
|---|
| 456 | + .llseek = no_llseek, |
|---|
| 463 | 457 | .mmap = spufs_cntl_mmap, |
|---|
| 464 | 458 | }; |
|---|
| 465 | 459 | |
|---|
| .. | .. |
|---|
| 472 | 466 | } |
|---|
| 473 | 467 | |
|---|
| 474 | 468 | static ssize_t |
|---|
| 475 | | -__spufs_regs_read(struct spu_context *ctx, char __user *buffer, |
|---|
| 476 | | - size_t size, loff_t *pos) |
|---|
| 469 | +spufs_regs_dump(struct spu_context *ctx, struct coredump_params *cprm) |
|---|
| 477 | 470 | { |
|---|
| 478 | | - struct spu_lscsa *lscsa = ctx->csa.lscsa; |
|---|
| 479 | | - return simple_read_from_buffer(buffer, size, pos, |
|---|
| 480 | | - lscsa->gprs, sizeof lscsa->gprs); |
|---|
| 471 | + return spufs_dump_emit(cprm, ctx->csa.lscsa->gprs, |
|---|
| 472 | + sizeof(ctx->csa.lscsa->gprs)); |
|---|
| 481 | 473 | } |
|---|
| 482 | 474 | |
|---|
| 483 | 475 | static ssize_t |
|---|
| .. | .. |
|---|
| 495 | 487 | ret = spu_acquire_saved(ctx); |
|---|
| 496 | 488 | if (ret) |
|---|
| 497 | 489 | return ret; |
|---|
| 498 | | - ret = __spufs_regs_read(ctx, buffer, size, pos); |
|---|
| 490 | + ret = simple_read_from_buffer(buffer, size, pos, ctx->csa.lscsa->gprs, |
|---|
| 491 | + sizeof(ctx->csa.lscsa->gprs)); |
|---|
| 499 | 492 | spu_release_saved(ctx); |
|---|
| 500 | 493 | return ret; |
|---|
| 501 | 494 | } |
|---|
| .. | .. |
|---|
| 530 | 523 | }; |
|---|
| 531 | 524 | |
|---|
| 532 | 525 | static ssize_t |
|---|
| 533 | | -__spufs_fpcr_read(struct spu_context *ctx, char __user * buffer, |
|---|
| 534 | | - size_t size, loff_t * pos) |
|---|
| 526 | +spufs_fpcr_dump(struct spu_context *ctx, struct coredump_params *cprm) |
|---|
| 535 | 527 | { |
|---|
| 536 | | - struct spu_lscsa *lscsa = ctx->csa.lscsa; |
|---|
| 537 | | - return simple_read_from_buffer(buffer, size, pos, |
|---|
| 538 | | - &lscsa->fpcr, sizeof(lscsa->fpcr)); |
|---|
| 528 | + return spufs_dump_emit(cprm, &ctx->csa.lscsa->fpcr, |
|---|
| 529 | + sizeof(ctx->csa.lscsa->fpcr)); |
|---|
| 539 | 530 | } |
|---|
| 540 | 531 | |
|---|
| 541 | 532 | static ssize_t |
|---|
| .. | .. |
|---|
| 548 | 539 | ret = spu_acquire_saved(ctx); |
|---|
| 549 | 540 | if (ret) |
|---|
| 550 | 541 | return ret; |
|---|
| 551 | | - ret = __spufs_fpcr_read(ctx, buffer, size, pos); |
|---|
| 542 | + ret = simple_read_from_buffer(buffer, size, pos, &ctx->csa.lscsa->fpcr, |
|---|
| 543 | + sizeof(ctx->csa.lscsa->fpcr)); |
|---|
| 552 | 544 | spu_release_saved(ctx); |
|---|
| 553 | 545 | return ret; |
|---|
| 554 | 546 | } |
|---|
| .. | .. |
|---|
| 588 | 580 | struct spufs_inode_info *i = SPUFS_I(inode); |
|---|
| 589 | 581 | file->private_data = i->i_ctx; |
|---|
| 590 | 582 | |
|---|
| 591 | | - return nonseekable_open(inode, file); |
|---|
| 583 | + return stream_open(inode, file); |
|---|
| 592 | 584 | } |
|---|
| 593 | 585 | |
|---|
| 594 | 586 | /* |
|---|
| .. | .. |
|---|
| 603 | 595 | size_t len, loff_t *pos) |
|---|
| 604 | 596 | { |
|---|
| 605 | 597 | struct spu_context *ctx = file->private_data; |
|---|
| 606 | | - u32 mbox_data, __user *udata; |
|---|
| 598 | + u32 mbox_data, __user *udata = (void __user *)buf; |
|---|
| 607 | 599 | ssize_t count; |
|---|
| 608 | 600 | |
|---|
| 609 | 601 | if (len < 4) |
|---|
| 610 | 602 | return -EINVAL; |
|---|
| 611 | | - |
|---|
| 612 | | - if (!access_ok(VERIFY_WRITE, buf, len)) |
|---|
| 613 | | - return -EFAULT; |
|---|
| 614 | | - |
|---|
| 615 | | - udata = (void __user *)buf; |
|---|
| 616 | 603 | |
|---|
| 617 | 604 | count = spu_acquire(ctx); |
|---|
| 618 | 605 | if (count) |
|---|
| .. | .. |
|---|
| 629 | 616 | * but still need to return the data we have |
|---|
| 630 | 617 | * read successfully so far. |
|---|
| 631 | 618 | */ |
|---|
| 632 | | - ret = __put_user(mbox_data, udata); |
|---|
| 619 | + ret = put_user(mbox_data, udata); |
|---|
| 633 | 620 | if (ret) { |
|---|
| 634 | 621 | if (!count) |
|---|
| 635 | 622 | count = -EFAULT; |
|---|
| .. | .. |
|---|
| 711 | 698 | size_t len, loff_t *pos) |
|---|
| 712 | 699 | { |
|---|
| 713 | 700 | struct spu_context *ctx = file->private_data; |
|---|
| 714 | | - u32 ibox_data, __user *udata; |
|---|
| 701 | + u32 ibox_data, __user *udata = (void __user *)buf; |
|---|
| 715 | 702 | ssize_t count; |
|---|
| 716 | 703 | |
|---|
| 717 | 704 | if (len < 4) |
|---|
| 718 | 705 | return -EINVAL; |
|---|
| 719 | | - |
|---|
| 720 | | - if (!access_ok(VERIFY_WRITE, buf, len)) |
|---|
| 721 | | - return -EFAULT; |
|---|
| 722 | | - |
|---|
| 723 | | - udata = (void __user *)buf; |
|---|
| 724 | 706 | |
|---|
| 725 | 707 | count = spu_acquire(ctx); |
|---|
| 726 | 708 | if (count) |
|---|
| .. | .. |
|---|
| 740 | 722 | } |
|---|
| 741 | 723 | |
|---|
| 742 | 724 | /* if we can't write at all, return -EFAULT */ |
|---|
| 743 | | - count = __put_user(ibox_data, udata); |
|---|
| 725 | + count = put_user(ibox_data, udata); |
|---|
| 744 | 726 | if (count) |
|---|
| 745 | 727 | goto out_unlock; |
|---|
| 746 | 728 | |
|---|
| .. | .. |
|---|
| 754 | 736 | * but still need to return the data we have |
|---|
| 755 | 737 | * read successfully so far. |
|---|
| 756 | 738 | */ |
|---|
| 757 | | - ret = __put_user(ibox_data, udata); |
|---|
| 739 | + ret = put_user(ibox_data, udata); |
|---|
| 758 | 740 | if (ret) |
|---|
| 759 | 741 | break; |
|---|
| 760 | 742 | } |
|---|
| .. | .. |
|---|
| 849 | 831 | size_t len, loff_t *pos) |
|---|
| 850 | 832 | { |
|---|
| 851 | 833 | struct spu_context *ctx = file->private_data; |
|---|
| 852 | | - u32 wbox_data, __user *udata; |
|---|
| 834 | + u32 wbox_data, __user *udata = (void __user *)buf; |
|---|
| 853 | 835 | ssize_t count; |
|---|
| 854 | 836 | |
|---|
| 855 | 837 | if (len < 4) |
|---|
| 856 | 838 | return -EINVAL; |
|---|
| 857 | 839 | |
|---|
| 858 | | - udata = (void __user *)buf; |
|---|
| 859 | | - if (!access_ok(VERIFY_READ, buf, len)) |
|---|
| 860 | | - return -EFAULT; |
|---|
| 861 | | - |
|---|
| 862 | | - if (__get_user(wbox_data, udata)) |
|---|
| 840 | + if (get_user(wbox_data, udata)) |
|---|
| 863 | 841 | return -EFAULT; |
|---|
| 864 | 842 | |
|---|
| 865 | 843 | count = spu_acquire(ctx); |
|---|
| .. | .. |
|---|
| 886 | 864 | /* write as much as possible */ |
|---|
| 887 | 865 | for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) { |
|---|
| 888 | 866 | int ret; |
|---|
| 889 | | - ret = __get_user(wbox_data, udata); |
|---|
| 867 | + ret = get_user(wbox_data, udata); |
|---|
| 890 | 868 | if (ret) |
|---|
| 891 | 869 | break; |
|---|
| 892 | 870 | |
|---|
| .. | .. |
|---|
| 980 | 958 | return 0; |
|---|
| 981 | 959 | } |
|---|
| 982 | 960 | |
|---|
| 983 | | -static ssize_t __spufs_signal1_read(struct spu_context *ctx, char __user *buf, |
|---|
| 984 | | - size_t len, loff_t *pos) |
|---|
| 961 | +static ssize_t spufs_signal1_dump(struct spu_context *ctx, |
|---|
| 962 | + struct coredump_params *cprm) |
|---|
| 985 | 963 | { |
|---|
| 986 | | - int ret = 0; |
|---|
| 987 | | - u32 data; |
|---|
| 964 | + if (!ctx->csa.spu_chnlcnt_RW[3]) |
|---|
| 965 | + return 0; |
|---|
| 966 | + return spufs_dump_emit(cprm, &ctx->csa.spu_chnldata_RW[3], |
|---|
| 967 | + sizeof(ctx->csa.spu_chnldata_RW[3])); |
|---|
| 968 | +} |
|---|
| 988 | 969 | |
|---|
| 989 | | - if (len < 4) |
|---|
| 970 | +static ssize_t __spufs_signal1_read(struct spu_context *ctx, char __user *buf, |
|---|
| 971 | + size_t len) |
|---|
| 972 | +{ |
|---|
| 973 | + if (len < sizeof(ctx->csa.spu_chnldata_RW[3])) |
|---|
| 990 | 974 | return -EINVAL; |
|---|
| 991 | | - |
|---|
| 992 | | - if (ctx->csa.spu_chnlcnt_RW[3]) { |
|---|
| 993 | | - data = ctx->csa.spu_chnldata_RW[3]; |
|---|
| 994 | | - ret = 4; |
|---|
| 995 | | - } |
|---|
| 996 | | - |
|---|
| 997 | | - if (!ret) |
|---|
| 998 | | - goto out; |
|---|
| 999 | | - |
|---|
| 1000 | | - if (copy_to_user(buf, &data, 4)) |
|---|
| 975 | + if (!ctx->csa.spu_chnlcnt_RW[3]) |
|---|
| 976 | + return 0; |
|---|
| 977 | + if (copy_to_user(buf, &ctx->csa.spu_chnldata_RW[3], |
|---|
| 978 | + sizeof(ctx->csa.spu_chnldata_RW[3]))) |
|---|
| 1001 | 979 | return -EFAULT; |
|---|
| 1002 | | - |
|---|
| 1003 | | -out: |
|---|
| 1004 | | - return ret; |
|---|
| 980 | + return sizeof(ctx->csa.spu_chnldata_RW[3]); |
|---|
| 1005 | 981 | } |
|---|
| 1006 | 982 | |
|---|
| 1007 | 983 | static ssize_t spufs_signal1_read(struct file *file, char __user *buf, |
|---|
| .. | .. |
|---|
| 1013 | 989 | ret = spu_acquire_saved(ctx); |
|---|
| 1014 | 990 | if (ret) |
|---|
| 1015 | 991 | return ret; |
|---|
| 1016 | | - ret = __spufs_signal1_read(ctx, buf, len, pos); |
|---|
| 992 | + ret = __spufs_signal1_read(ctx, buf, len); |
|---|
| 1017 | 993 | spu_release_saved(ctx); |
|---|
| 1018 | 994 | |
|---|
| 1019 | 995 | return ret; |
|---|
| .. | .. |
|---|
| 1117 | 1093 | return 0; |
|---|
| 1118 | 1094 | } |
|---|
| 1119 | 1095 | |
|---|
| 1120 | | -static ssize_t __spufs_signal2_read(struct spu_context *ctx, char __user *buf, |
|---|
| 1121 | | - size_t len, loff_t *pos) |
|---|
| 1096 | +static ssize_t spufs_signal2_dump(struct spu_context *ctx, |
|---|
| 1097 | + struct coredump_params *cprm) |
|---|
| 1122 | 1098 | { |
|---|
| 1123 | | - int ret = 0; |
|---|
| 1124 | | - u32 data; |
|---|
| 1099 | + if (!ctx->csa.spu_chnlcnt_RW[4]) |
|---|
| 1100 | + return 0; |
|---|
| 1101 | + return spufs_dump_emit(cprm, &ctx->csa.spu_chnldata_RW[4], |
|---|
| 1102 | + sizeof(ctx->csa.spu_chnldata_RW[4])); |
|---|
| 1103 | +} |
|---|
| 1125 | 1104 | |
|---|
| 1126 | | - if (len < 4) |
|---|
| 1105 | +static ssize_t __spufs_signal2_read(struct spu_context *ctx, char __user *buf, |
|---|
| 1106 | + size_t len) |
|---|
| 1107 | +{ |
|---|
| 1108 | + if (len < sizeof(ctx->csa.spu_chnldata_RW[4])) |
|---|
| 1127 | 1109 | return -EINVAL; |
|---|
| 1128 | | - |
|---|
| 1129 | | - if (ctx->csa.spu_chnlcnt_RW[4]) { |
|---|
| 1130 | | - data = ctx->csa.spu_chnldata_RW[4]; |
|---|
| 1131 | | - ret = 4; |
|---|
| 1132 | | - } |
|---|
| 1133 | | - |
|---|
| 1134 | | - if (!ret) |
|---|
| 1135 | | - goto out; |
|---|
| 1136 | | - |
|---|
| 1137 | | - if (copy_to_user(buf, &data, 4)) |
|---|
| 1110 | + if (!ctx->csa.spu_chnlcnt_RW[4]) |
|---|
| 1111 | + return 0; |
|---|
| 1112 | + if (copy_to_user(buf, &ctx->csa.spu_chnldata_RW[4], |
|---|
| 1113 | + sizeof(ctx->csa.spu_chnldata_RW[4]))) |
|---|
| 1138 | 1114 | return -EFAULT; |
|---|
| 1139 | | - |
|---|
| 1140 | | -out: |
|---|
| 1141 | | - return ret; |
|---|
| 1115 | + return sizeof(ctx->csa.spu_chnldata_RW[4]); |
|---|
| 1142 | 1116 | } |
|---|
| 1143 | 1117 | |
|---|
| 1144 | 1118 | static ssize_t spufs_signal2_read(struct file *file, char __user *buf, |
|---|
| .. | .. |
|---|
| 1150 | 1124 | ret = spu_acquire_saved(ctx); |
|---|
| 1151 | 1125 | if (ret) |
|---|
| 1152 | 1126 | return ret; |
|---|
| 1153 | | - ret = __spufs_signal2_read(ctx, buf, len, pos); |
|---|
| 1127 | + ret = __spufs_signal2_read(ctx, buf, len); |
|---|
| 1154 | 1128 | spu_release_saved(ctx); |
|---|
| 1155 | 1129 | |
|---|
| 1156 | 1130 | return ret; |
|---|
| .. | .. |
|---|
| 1974 | 1948 | .release = single_release, |
|---|
| 1975 | 1949 | }; |
|---|
| 1976 | 1950 | |
|---|
| 1977 | | -static ssize_t __spufs_mbox_info_read(struct spu_context *ctx, |
|---|
| 1978 | | - char __user *buf, size_t len, loff_t *pos) |
|---|
| 1951 | +static ssize_t spufs_mbox_info_dump(struct spu_context *ctx, |
|---|
| 1952 | + struct coredump_params *cprm) |
|---|
| 1979 | 1953 | { |
|---|
| 1980 | | - u32 data; |
|---|
| 1981 | | - |
|---|
| 1982 | | - /* EOF if there's no entry in the mbox */ |
|---|
| 1983 | 1954 | if (!(ctx->csa.prob.mb_stat_R & 0x0000ff)) |
|---|
| 1984 | 1955 | return 0; |
|---|
| 1985 | | - |
|---|
| 1986 | | - data = ctx->csa.prob.pu_mb_R; |
|---|
| 1987 | | - |
|---|
| 1988 | | - return simple_read_from_buffer(buf, len, pos, &data, sizeof data); |
|---|
| 1956 | + return spufs_dump_emit(cprm, &ctx->csa.prob.pu_mb_R, |
|---|
| 1957 | + sizeof(ctx->csa.prob.pu_mb_R)); |
|---|
| 1989 | 1958 | } |
|---|
| 1990 | 1959 | |
|---|
| 1991 | 1960 | static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, |
|---|
| .. | .. |
|---|
| 1994 | 1963 | struct spu_context *ctx = file->private_data; |
|---|
| 1995 | 1964 | u32 stat, data; |
|---|
| 1996 | 1965 | int ret; |
|---|
| 1997 | | - |
|---|
| 1998 | | - if (!access_ok(VERIFY_WRITE, buf, len)) |
|---|
| 1999 | | - return -EFAULT; |
|---|
| 2000 | 1966 | |
|---|
| 2001 | 1967 | ret = spu_acquire_saved(ctx); |
|---|
| 2002 | 1968 | if (ret) |
|---|
| .. | .. |
|---|
| 2020 | 1986 | .llseek = generic_file_llseek, |
|---|
| 2021 | 1987 | }; |
|---|
| 2022 | 1988 | |
|---|
| 2023 | | -static ssize_t __spufs_ibox_info_read(struct spu_context *ctx, |
|---|
| 2024 | | - char __user *buf, size_t len, loff_t *pos) |
|---|
| 1989 | +static ssize_t spufs_ibox_info_dump(struct spu_context *ctx, |
|---|
| 1990 | + struct coredump_params *cprm) |
|---|
| 2025 | 1991 | { |
|---|
| 2026 | | - u32 data; |
|---|
| 2027 | | - |
|---|
| 2028 | | - /* EOF if there's no entry in the ibox */ |
|---|
| 2029 | 1992 | if (!(ctx->csa.prob.mb_stat_R & 0xff0000)) |
|---|
| 2030 | 1993 | return 0; |
|---|
| 2031 | | - |
|---|
| 2032 | | - data = ctx->csa.priv2.puint_mb_R; |
|---|
| 2033 | | - |
|---|
| 2034 | | - return simple_read_from_buffer(buf, len, pos, &data, sizeof data); |
|---|
| 1994 | + return spufs_dump_emit(cprm, &ctx->csa.priv2.puint_mb_R, |
|---|
| 1995 | + sizeof(ctx->csa.priv2.puint_mb_R)); |
|---|
| 2035 | 1996 | } |
|---|
| 2036 | 1997 | |
|---|
| 2037 | 1998 | static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf, |
|---|
| .. | .. |
|---|
| 2040 | 2001 | struct spu_context *ctx = file->private_data; |
|---|
| 2041 | 2002 | u32 stat, data; |
|---|
| 2042 | 2003 | int ret; |
|---|
| 2043 | | - |
|---|
| 2044 | | - if (!access_ok(VERIFY_WRITE, buf, len)) |
|---|
| 2045 | | - return -EFAULT; |
|---|
| 2046 | 2004 | |
|---|
| 2047 | 2005 | ret = spu_acquire_saved(ctx); |
|---|
| 2048 | 2006 | if (ret) |
|---|
| .. | .. |
|---|
| 2071 | 2029 | return (4 - ((ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8)) * sizeof(u32); |
|---|
| 2072 | 2030 | } |
|---|
| 2073 | 2031 | |
|---|
| 2074 | | -static ssize_t __spufs_wbox_info_read(struct spu_context *ctx, |
|---|
| 2075 | | - char __user *buf, size_t len, loff_t *pos) |
|---|
| 2032 | +static ssize_t spufs_wbox_info_dump(struct spu_context *ctx, |
|---|
| 2033 | + struct coredump_params *cprm) |
|---|
| 2076 | 2034 | { |
|---|
| 2077 | | - int i, cnt; |
|---|
| 2078 | | - u32 data[4]; |
|---|
| 2079 | | - u32 wbox_stat; |
|---|
| 2080 | | - |
|---|
| 2081 | | - wbox_stat = ctx->csa.prob.mb_stat_R; |
|---|
| 2082 | | - cnt = spufs_wbox_info_cnt(ctx); |
|---|
| 2083 | | - for (i = 0; i < cnt; i++) { |
|---|
| 2084 | | - data[i] = ctx->csa.spu_mailbox_data[i]; |
|---|
| 2085 | | - } |
|---|
| 2086 | | - |
|---|
| 2087 | | - return simple_read_from_buffer(buf, len, pos, &data, |
|---|
| 2088 | | - cnt * sizeof(u32)); |
|---|
| 2035 | + return spufs_dump_emit(cprm, &ctx->csa.spu_mailbox_data, |
|---|
| 2036 | + spufs_wbox_info_cnt(ctx)); |
|---|
| 2089 | 2037 | } |
|---|
| 2090 | 2038 | |
|---|
| 2091 | 2039 | static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, |
|---|
| .. | .. |
|---|
| 2094 | 2042 | struct spu_context *ctx = file->private_data; |
|---|
| 2095 | 2043 | u32 data[ARRAY_SIZE(ctx->csa.spu_mailbox_data)]; |
|---|
| 2096 | 2044 | int ret, count; |
|---|
| 2097 | | - |
|---|
| 2098 | | - if (!access_ok(VERIFY_WRITE, buf, len)) |
|---|
| 2099 | | - return -EFAULT; |
|---|
| 2100 | 2045 | |
|---|
| 2101 | 2046 | ret = spu_acquire_saved(ctx); |
|---|
| 2102 | 2047 | if (ret) |
|---|
| .. | .. |
|---|
| 2138 | 2083 | } |
|---|
| 2139 | 2084 | } |
|---|
| 2140 | 2085 | |
|---|
| 2141 | | -static ssize_t __spufs_dma_info_read(struct spu_context *ctx, |
|---|
| 2142 | | - char __user *buf, size_t len, loff_t *pos) |
|---|
| 2086 | +static ssize_t spufs_dma_info_dump(struct spu_context *ctx, |
|---|
| 2087 | + struct coredump_params *cprm) |
|---|
| 2143 | 2088 | { |
|---|
| 2144 | 2089 | struct spu_dma_info info; |
|---|
| 2145 | 2090 | |
|---|
| 2146 | 2091 | spufs_get_dma_info(ctx, &info); |
|---|
| 2147 | | - |
|---|
| 2148 | | - return simple_read_from_buffer(buf, len, pos, &info, |
|---|
| 2149 | | - sizeof info); |
|---|
| 2092 | + return spufs_dump_emit(cprm, &info, sizeof(info)); |
|---|
| 2150 | 2093 | } |
|---|
| 2151 | 2094 | |
|---|
| 2152 | 2095 | static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, |
|---|
| .. | .. |
|---|
| 2155 | 2098 | struct spu_context *ctx = file->private_data; |
|---|
| 2156 | 2099 | struct spu_dma_info info; |
|---|
| 2157 | 2100 | int ret; |
|---|
| 2158 | | - |
|---|
| 2159 | | - if (!access_ok(VERIFY_WRITE, buf, len)) |
|---|
| 2160 | | - return -EFAULT; |
|---|
| 2161 | 2101 | |
|---|
| 2162 | 2102 | ret = spu_acquire_saved(ctx); |
|---|
| 2163 | 2103 | if (ret) |
|---|
| .. | .. |
|---|
| 2197 | 2137 | } |
|---|
| 2198 | 2138 | } |
|---|
| 2199 | 2139 | |
|---|
| 2200 | | -static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx, |
|---|
| 2201 | | - char __user *buf, size_t len, loff_t *pos) |
|---|
| 2140 | +static ssize_t spufs_proxydma_info_dump(struct spu_context *ctx, |
|---|
| 2141 | + struct coredump_params *cprm) |
|---|
| 2202 | 2142 | { |
|---|
| 2203 | 2143 | struct spu_proxydma_info info; |
|---|
| 2204 | | - int ret = sizeof info; |
|---|
| 2205 | | - |
|---|
| 2206 | | - if (len < ret) |
|---|
| 2207 | | - return -EINVAL; |
|---|
| 2208 | | - |
|---|
| 2209 | | - if (!access_ok(VERIFY_WRITE, buf, len)) |
|---|
| 2210 | | - return -EFAULT; |
|---|
| 2211 | 2144 | |
|---|
| 2212 | 2145 | spufs_get_proxydma_info(ctx, &info); |
|---|
| 2213 | | - |
|---|
| 2214 | | - return simple_read_from_buffer(buf, len, pos, &info, |
|---|
| 2215 | | - sizeof info); |
|---|
| 2146 | + return spufs_dump_emit(cprm, &info, sizeof(info)); |
|---|
| 2216 | 2147 | } |
|---|
| 2217 | 2148 | |
|---|
| 2218 | 2149 | static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, |
|---|
| .. | .. |
|---|
| 2221 | 2152 | struct spu_context *ctx = file->private_data; |
|---|
| 2222 | 2153 | struct spu_proxydma_info info; |
|---|
| 2223 | 2154 | int ret; |
|---|
| 2155 | + |
|---|
| 2156 | + if (len < sizeof(info)) |
|---|
| 2157 | + return -EINVAL; |
|---|
| 2224 | 2158 | |
|---|
| 2225 | 2159 | ret = spu_acquire_saved(ctx); |
|---|
| 2226 | 2160 | if (ret) |
|---|
| .. | .. |
|---|
| 2375 | 2309 | goto out; |
|---|
| 2376 | 2310 | } |
|---|
| 2377 | 2311 | |
|---|
| 2378 | | - ctx->switch_log = kmalloc(sizeof(struct switch_log) + |
|---|
| 2379 | | - SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry), |
|---|
| 2380 | | - GFP_KERNEL); |
|---|
| 2312 | + ctx->switch_log = kmalloc(struct_size(ctx->switch_log, log, |
|---|
| 2313 | + SWITCH_LOG_BUFSIZE), GFP_KERNEL); |
|---|
| 2381 | 2314 | |
|---|
| 2382 | 2315 | if (!ctx->switch_log) { |
|---|
| 2383 | 2316 | rc = -ENOMEM; |
|---|
| .. | .. |
|---|
| 2676 | 2609 | }; |
|---|
| 2677 | 2610 | |
|---|
| 2678 | 2611 | const struct spufs_coredump_reader spufs_coredump_read[] = { |
|---|
| 2679 | | - { "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])}, |
|---|
| 2680 | | - { "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) }, |
|---|
| 2612 | + { "regs", spufs_regs_dump, NULL, sizeof(struct spu_reg128[128])}, |
|---|
| 2613 | + { "fpcr", spufs_fpcr_dump, NULL, sizeof(struct spu_reg128) }, |
|---|
| 2681 | 2614 | { "lslr", NULL, spufs_lslr_get, 19 }, |
|---|
| 2682 | 2615 | { "decr", NULL, spufs_decr_get, 19 }, |
|---|
| 2683 | 2616 | { "decr_status", NULL, spufs_decr_status_get, 19 }, |
|---|
| 2684 | | - { "mem", __spufs_mem_read, NULL, LS_SIZE, }, |
|---|
| 2685 | | - { "signal1", __spufs_signal1_read, NULL, sizeof(u32) }, |
|---|
| 2617 | + { "mem", spufs_mem_dump, NULL, LS_SIZE, }, |
|---|
| 2618 | + { "signal1", spufs_signal1_dump, NULL, sizeof(u32) }, |
|---|
| 2686 | 2619 | { "signal1_type", NULL, spufs_signal1_type_get, 19 }, |
|---|
| 2687 | | - { "signal2", __spufs_signal2_read, NULL, sizeof(u32) }, |
|---|
| 2620 | + { "signal2", spufs_signal2_dump, NULL, sizeof(u32) }, |
|---|
| 2688 | 2621 | { "signal2_type", NULL, spufs_signal2_type_get, 19 }, |
|---|
| 2689 | 2622 | { "event_mask", NULL, spufs_event_mask_get, 19 }, |
|---|
| 2690 | 2623 | { "event_status", NULL, spufs_event_status_get, 19 }, |
|---|
| 2691 | | - { "mbox_info", __spufs_mbox_info_read, NULL, sizeof(u32) }, |
|---|
| 2692 | | - { "ibox_info", __spufs_ibox_info_read, NULL, sizeof(u32) }, |
|---|
| 2693 | | - { "wbox_info", __spufs_wbox_info_read, NULL, 4 * sizeof(u32)}, |
|---|
| 2694 | | - { "dma_info", __spufs_dma_info_read, NULL, sizeof(struct spu_dma_info)}, |
|---|
| 2695 | | - { "proxydma_info", __spufs_proxydma_info_read, |
|---|
| 2624 | + { "mbox_info", spufs_mbox_info_dump, NULL, sizeof(u32) }, |
|---|
| 2625 | + { "ibox_info", spufs_ibox_info_dump, NULL, sizeof(u32) }, |
|---|
| 2626 | + { "wbox_info", spufs_wbox_info_dump, NULL, 4 * sizeof(u32)}, |
|---|
| 2627 | + { "dma_info", spufs_dma_info_dump, NULL, sizeof(struct spu_dma_info)}, |
|---|
| 2628 | + { "proxydma_info", spufs_proxydma_info_dump, |
|---|
| 2696 | 2629 | NULL, sizeof(struct spu_proxydma_info)}, |
|---|
| 2697 | 2630 | { "object-id", NULL, spufs_object_id_get, 19 }, |
|---|
| 2698 | 2631 | { "npc", NULL, spufs_npc_get, 19 }, |
|---|