.. | .. |
---|
| 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 }, |
---|