.. | .. |
---|
24 | 24 | #include <linux/seccomp.h> |
---|
25 | 25 | #include <linux/compat.h> |
---|
26 | 26 | #include <trace/syscall.h> |
---|
27 | | -#include <asm/segment.h> |
---|
28 | 27 | #include <asm/page.h> |
---|
29 | | -#include <asm/pgtable.h> |
---|
30 | | -#include <asm/pgalloc.h> |
---|
31 | 28 | #include <linux/uaccess.h> |
---|
32 | 29 | #include <asm/unistd.h> |
---|
33 | 30 | #include <asm/switch_to.h> |
---|
.. | .. |
---|
503 | 500 | } |
---|
504 | 501 | return 0; |
---|
505 | 502 | case PTRACE_GET_LAST_BREAK: |
---|
506 | | - put_user(child->thread.last_break, |
---|
507 | | - (unsigned long __user *) data); |
---|
508 | | - return 0; |
---|
| 503 | + return put_user(child->thread.last_break, (unsigned long __user *)data); |
---|
509 | 504 | case PTRACE_ENABLE_TE: |
---|
510 | 505 | if (!MACHINE_HAS_TE) |
---|
511 | 506 | return -EIO; |
---|
.. | .. |
---|
857 | 852 | } |
---|
858 | 853 | return 0; |
---|
859 | 854 | case PTRACE_GET_LAST_BREAK: |
---|
860 | | - put_user(child->thread.last_break, |
---|
861 | | - (unsigned int __user *) data); |
---|
862 | | - return 0; |
---|
| 855 | + return put_user(child->thread.last_break, (unsigned int __user *)data); |
---|
863 | 856 | } |
---|
864 | 857 | return compat_ptrace_request(child, request, addr, data); |
---|
865 | 858 | } |
---|
.. | .. |
---|
868 | 861 | asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) |
---|
869 | 862 | { |
---|
870 | 863 | unsigned long mask = -1UL; |
---|
| 864 | + long ret = -1; |
---|
| 865 | + |
---|
| 866 | + if (is_compat_task()) |
---|
| 867 | + mask = 0xffffffff; |
---|
871 | 868 | |
---|
872 | 869 | /* |
---|
873 | 870 | * The sysc_tracesys code in entry.S stored the system |
---|
874 | 871 | * call number to gprs[2]. |
---|
875 | 872 | */ |
---|
876 | 873 | if (test_thread_flag(TIF_SYSCALL_TRACE) && |
---|
877 | | - (tracehook_report_syscall_entry(regs) || |
---|
878 | | - regs->gprs[2] >= NR_syscalls)) { |
---|
| 874 | + tracehook_report_syscall_entry(regs)) { |
---|
879 | 875 | /* |
---|
880 | | - * Tracing decided this syscall should not happen or the |
---|
881 | | - * debugger stored an invalid system call number. Skip |
---|
| 876 | + * Tracing decided this syscall should not happen. Skip |
---|
882 | 877 | * the system call and the system call restart handling. |
---|
883 | 878 | */ |
---|
884 | | - clear_pt_regs_flag(regs, PIF_SYSCALL); |
---|
885 | | - return -1; |
---|
| 879 | + goto skip; |
---|
886 | 880 | } |
---|
887 | 881 | |
---|
| 882 | +#ifdef CONFIG_SECCOMP |
---|
888 | 883 | /* Do the secure computing check after ptrace. */ |
---|
889 | | - if (secure_computing(NULL)) { |
---|
890 | | - /* seccomp failures shouldn't expose any additional code. */ |
---|
891 | | - return -1; |
---|
| 884 | + if (unlikely(test_thread_flag(TIF_SECCOMP))) { |
---|
| 885 | + struct seccomp_data sd; |
---|
| 886 | + |
---|
| 887 | + if (is_compat_task()) { |
---|
| 888 | + sd.instruction_pointer = regs->psw.addr & 0x7fffffff; |
---|
| 889 | + sd.arch = AUDIT_ARCH_S390; |
---|
| 890 | + } else { |
---|
| 891 | + sd.instruction_pointer = regs->psw.addr; |
---|
| 892 | + sd.arch = AUDIT_ARCH_S390X; |
---|
| 893 | + } |
---|
| 894 | + |
---|
| 895 | + sd.nr = regs->int_code & 0xffff; |
---|
| 896 | + sd.args[0] = regs->orig_gpr2 & mask; |
---|
| 897 | + sd.args[1] = regs->gprs[3] & mask; |
---|
| 898 | + sd.args[2] = regs->gprs[4] & mask; |
---|
| 899 | + sd.args[3] = regs->gprs[5] & mask; |
---|
| 900 | + sd.args[4] = regs->gprs[6] & mask; |
---|
| 901 | + sd.args[5] = regs->gprs[7] & mask; |
---|
| 902 | + |
---|
| 903 | + if (__secure_computing(&sd) == -1) |
---|
| 904 | + goto skip; |
---|
892 | 905 | } |
---|
| 906 | +#endif /* CONFIG_SECCOMP */ |
---|
893 | 907 | |
---|
894 | 908 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
---|
895 | | - trace_sys_enter(regs, regs->gprs[2]); |
---|
| 909 | + trace_sys_enter(regs, regs->int_code & 0xffff); |
---|
896 | 910 | |
---|
897 | | - if (is_compat_task()) |
---|
898 | | - mask = 0xffffffff; |
---|
899 | 911 | |
---|
900 | | - audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask, |
---|
| 912 | + audit_syscall_entry(regs->int_code & 0xffff, regs->orig_gpr2 & mask, |
---|
901 | 913 | regs->gprs[3] &mask, regs->gprs[4] &mask, |
---|
902 | 914 | regs->gprs[5] &mask); |
---|
903 | 915 | |
---|
| 916 | + if ((signed long)regs->gprs[2] >= NR_syscalls) { |
---|
| 917 | + regs->gprs[2] = -ENOSYS; |
---|
| 918 | + ret = -ENOSYS; |
---|
| 919 | + } |
---|
904 | 920 | return regs->gprs[2]; |
---|
| 921 | +skip: |
---|
| 922 | + clear_pt_regs_flag(regs, PIF_SYSCALL); |
---|
| 923 | + return ret; |
---|
905 | 924 | } |
---|
906 | 925 | |
---|
907 | 926 | asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) |
---|
.. | .. |
---|
921 | 940 | |
---|
922 | 941 | static int s390_regs_get(struct task_struct *target, |
---|
923 | 942 | const struct user_regset *regset, |
---|
924 | | - unsigned int pos, unsigned int count, |
---|
925 | | - void *kbuf, void __user *ubuf) |
---|
| 943 | + struct membuf to) |
---|
926 | 944 | { |
---|
| 945 | + unsigned pos; |
---|
927 | 946 | if (target == current) |
---|
928 | 947 | save_access_regs(target->thread.acrs); |
---|
929 | 948 | |
---|
930 | | - if (kbuf) { |
---|
931 | | - unsigned long *k = kbuf; |
---|
932 | | - while (count > 0) { |
---|
933 | | - *k++ = __peek_user(target, pos); |
---|
934 | | - count -= sizeof(*k); |
---|
935 | | - pos += sizeof(*k); |
---|
936 | | - } |
---|
937 | | - } else { |
---|
938 | | - unsigned long __user *u = ubuf; |
---|
939 | | - while (count > 0) { |
---|
940 | | - if (__put_user(__peek_user(target, pos), u++)) |
---|
941 | | - return -EFAULT; |
---|
942 | | - count -= sizeof(*u); |
---|
943 | | - pos += sizeof(*u); |
---|
944 | | - } |
---|
945 | | - } |
---|
| 949 | + for (pos = 0; pos < sizeof(s390_regs); pos += sizeof(long)) |
---|
| 950 | + membuf_store(&to, __peek_user(target, pos)); |
---|
946 | 951 | return 0; |
---|
947 | 952 | } |
---|
948 | 953 | |
---|
.. | .. |
---|
983 | 988 | } |
---|
984 | 989 | |
---|
985 | 990 | static int s390_fpregs_get(struct task_struct *target, |
---|
986 | | - const struct user_regset *regset, unsigned int pos, |
---|
987 | | - unsigned int count, void *kbuf, void __user *ubuf) |
---|
| 991 | + const struct user_regset *regset, |
---|
| 992 | + struct membuf to) |
---|
988 | 993 | { |
---|
989 | 994 | _s390_fp_regs fp_regs; |
---|
990 | 995 | |
---|
.. | .. |
---|
994 | 999 | fp_regs.fpc = target->thread.fpu.fpc; |
---|
995 | 1000 | fpregs_store(&fp_regs, &target->thread.fpu); |
---|
996 | 1001 | |
---|
997 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
998 | | - &fp_regs, 0, -1); |
---|
| 1002 | + return membuf_write(&to, &fp_regs, sizeof(fp_regs)); |
---|
999 | 1003 | } |
---|
1000 | 1004 | |
---|
1001 | 1005 | static int s390_fpregs_set(struct task_struct *target, |
---|
.. | .. |
---|
1042 | 1046 | |
---|
1043 | 1047 | static int s390_last_break_get(struct task_struct *target, |
---|
1044 | 1048 | const struct user_regset *regset, |
---|
1045 | | - unsigned int pos, unsigned int count, |
---|
1046 | | - void *kbuf, void __user *ubuf) |
---|
| 1049 | + struct membuf to) |
---|
1047 | 1050 | { |
---|
1048 | | - if (count > 0) { |
---|
1049 | | - if (kbuf) { |
---|
1050 | | - unsigned long *k = kbuf; |
---|
1051 | | - *k = target->thread.last_break; |
---|
1052 | | - } else { |
---|
1053 | | - unsigned long __user *u = ubuf; |
---|
1054 | | - if (__put_user(target->thread.last_break, u)) |
---|
1055 | | - return -EFAULT; |
---|
1056 | | - } |
---|
1057 | | - } |
---|
1058 | | - return 0; |
---|
| 1051 | + return membuf_store(&to, target->thread.last_break); |
---|
1059 | 1052 | } |
---|
1060 | 1053 | |
---|
1061 | 1054 | static int s390_last_break_set(struct task_struct *target, |
---|
.. | .. |
---|
1068 | 1061 | |
---|
1069 | 1062 | static int s390_tdb_get(struct task_struct *target, |
---|
1070 | 1063 | const struct user_regset *regset, |
---|
1071 | | - unsigned int pos, unsigned int count, |
---|
1072 | | - void *kbuf, void __user *ubuf) |
---|
| 1064 | + struct membuf to) |
---|
1073 | 1065 | { |
---|
1074 | 1066 | struct pt_regs *regs = task_pt_regs(target); |
---|
1075 | | - unsigned char *data; |
---|
1076 | 1067 | |
---|
1077 | 1068 | if (!(regs->int_code & 0x200)) |
---|
1078 | 1069 | return -ENODATA; |
---|
1079 | | - data = target->thread.trap_tdb; |
---|
1080 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, data, 0, 256); |
---|
| 1070 | + return membuf_write(&to, target->thread.trap_tdb, 256); |
---|
1081 | 1071 | } |
---|
1082 | 1072 | |
---|
1083 | 1073 | static int s390_tdb_set(struct task_struct *target, |
---|
.. | .. |
---|
1090 | 1080 | |
---|
1091 | 1081 | static int s390_vxrs_low_get(struct task_struct *target, |
---|
1092 | 1082 | const struct user_regset *regset, |
---|
1093 | | - unsigned int pos, unsigned int count, |
---|
1094 | | - void *kbuf, void __user *ubuf) |
---|
| 1083 | + struct membuf to) |
---|
1095 | 1084 | { |
---|
1096 | 1085 | __u64 vxrs[__NUM_VXRS_LOW]; |
---|
1097 | 1086 | int i; |
---|
.. | .. |
---|
1102 | 1091 | save_fpu_regs(); |
---|
1103 | 1092 | for (i = 0; i < __NUM_VXRS_LOW; i++) |
---|
1104 | 1093 | vxrs[i] = *((__u64 *)(target->thread.fpu.vxrs + i) + 1); |
---|
1105 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1); |
---|
| 1094 | + return membuf_write(&to, vxrs, sizeof(vxrs)); |
---|
1106 | 1095 | } |
---|
1107 | 1096 | |
---|
1108 | 1097 | static int s390_vxrs_low_set(struct task_struct *target, |
---|
.. | .. |
---|
1131 | 1120 | |
---|
1132 | 1121 | static int s390_vxrs_high_get(struct task_struct *target, |
---|
1133 | 1122 | const struct user_regset *regset, |
---|
1134 | | - unsigned int pos, unsigned int count, |
---|
1135 | | - void *kbuf, void __user *ubuf) |
---|
| 1123 | + struct membuf to) |
---|
1136 | 1124 | { |
---|
1137 | | - __vector128 vxrs[__NUM_VXRS_HIGH]; |
---|
1138 | | - |
---|
1139 | 1125 | if (!MACHINE_HAS_VX) |
---|
1140 | 1126 | return -ENODEV; |
---|
1141 | 1127 | if (target == current) |
---|
1142 | 1128 | save_fpu_regs(); |
---|
1143 | | - memcpy(vxrs, target->thread.fpu.vxrs + __NUM_VXRS_LOW, sizeof(vxrs)); |
---|
1144 | | - |
---|
1145 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1); |
---|
| 1129 | + return membuf_write(&to, target->thread.fpu.vxrs + __NUM_VXRS_LOW, |
---|
| 1130 | + __NUM_VXRS_HIGH * sizeof(__vector128)); |
---|
1146 | 1131 | } |
---|
1147 | 1132 | |
---|
1148 | 1133 | static int s390_vxrs_high_set(struct task_struct *target, |
---|
.. | .. |
---|
1164 | 1149 | |
---|
1165 | 1150 | static int s390_system_call_get(struct task_struct *target, |
---|
1166 | 1151 | const struct user_regset *regset, |
---|
1167 | | - unsigned int pos, unsigned int count, |
---|
1168 | | - void *kbuf, void __user *ubuf) |
---|
| 1152 | + struct membuf to) |
---|
1169 | 1153 | { |
---|
1170 | | - unsigned int *data = &target->thread.system_call; |
---|
1171 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
1172 | | - data, 0, sizeof(unsigned int)); |
---|
| 1154 | + return membuf_store(&to, target->thread.system_call); |
---|
1173 | 1155 | } |
---|
1174 | 1156 | |
---|
1175 | 1157 | static int s390_system_call_set(struct task_struct *target, |
---|
.. | .. |
---|
1184 | 1166 | |
---|
1185 | 1167 | static int s390_gs_cb_get(struct task_struct *target, |
---|
1186 | 1168 | const struct user_regset *regset, |
---|
1187 | | - unsigned int pos, unsigned int count, |
---|
1188 | | - void *kbuf, void __user *ubuf) |
---|
| 1169 | + struct membuf to) |
---|
1189 | 1170 | { |
---|
1190 | 1171 | struct gs_cb *data = target->thread.gs_cb; |
---|
1191 | 1172 | |
---|
.. | .. |
---|
1195 | 1176 | return -ENODATA; |
---|
1196 | 1177 | if (target == current) |
---|
1197 | 1178 | save_gs_cb(data); |
---|
1198 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
1199 | | - data, 0, sizeof(struct gs_cb)); |
---|
| 1179 | + return membuf_write(&to, data, sizeof(struct gs_cb)); |
---|
1200 | 1180 | } |
---|
1201 | 1181 | |
---|
1202 | 1182 | static int s390_gs_cb_set(struct task_struct *target, |
---|
.. | .. |
---|
1240 | 1220 | |
---|
1241 | 1221 | static int s390_gs_bc_get(struct task_struct *target, |
---|
1242 | 1222 | const struct user_regset *regset, |
---|
1243 | | - unsigned int pos, unsigned int count, |
---|
1244 | | - void *kbuf, void __user *ubuf) |
---|
| 1223 | + struct membuf to) |
---|
1245 | 1224 | { |
---|
1246 | 1225 | struct gs_cb *data = target->thread.gs_bc_cb; |
---|
1247 | 1226 | |
---|
.. | .. |
---|
1249 | 1228 | return -ENODEV; |
---|
1250 | 1229 | if (!data) |
---|
1251 | 1230 | return -ENODATA; |
---|
1252 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
1253 | | - data, 0, sizeof(struct gs_cb)); |
---|
| 1231 | + return membuf_write(&to, data, sizeof(struct gs_cb)); |
---|
1254 | 1232 | } |
---|
1255 | 1233 | |
---|
1256 | 1234 | static int s390_gs_bc_set(struct task_struct *target, |
---|
.. | .. |
---|
1300 | 1278 | |
---|
1301 | 1279 | static int s390_runtime_instr_get(struct task_struct *target, |
---|
1302 | 1280 | const struct user_regset *regset, |
---|
1303 | | - unsigned int pos, unsigned int count, |
---|
1304 | | - void *kbuf, void __user *ubuf) |
---|
| 1281 | + struct membuf to) |
---|
1305 | 1282 | { |
---|
1306 | 1283 | struct runtime_instr_cb *data = target->thread.ri_cb; |
---|
1307 | 1284 | |
---|
.. | .. |
---|
1310 | 1287 | if (!data) |
---|
1311 | 1288 | return -ENODATA; |
---|
1312 | 1289 | |
---|
1313 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
1314 | | - data, 0, sizeof(struct runtime_instr_cb)); |
---|
| 1290 | + return membuf_write(&to, data, sizeof(struct runtime_instr_cb)); |
---|
1315 | 1291 | } |
---|
1316 | 1292 | |
---|
1317 | 1293 | static int s390_runtime_instr_set(struct task_struct *target, |
---|
.. | .. |
---|
1371 | 1347 | .n = sizeof(s390_regs) / sizeof(long), |
---|
1372 | 1348 | .size = sizeof(long), |
---|
1373 | 1349 | .align = sizeof(long), |
---|
1374 | | - .get = s390_regs_get, |
---|
| 1350 | + .regset_get = s390_regs_get, |
---|
1375 | 1351 | .set = s390_regs_set, |
---|
1376 | 1352 | }, |
---|
1377 | 1353 | { |
---|
.. | .. |
---|
1379 | 1355 | .n = sizeof(s390_fp_regs) / sizeof(long), |
---|
1380 | 1356 | .size = sizeof(long), |
---|
1381 | 1357 | .align = sizeof(long), |
---|
1382 | | - .get = s390_fpregs_get, |
---|
| 1358 | + .regset_get = s390_fpregs_get, |
---|
1383 | 1359 | .set = s390_fpregs_set, |
---|
1384 | 1360 | }, |
---|
1385 | 1361 | { |
---|
.. | .. |
---|
1387 | 1363 | .n = 1, |
---|
1388 | 1364 | .size = sizeof(unsigned int), |
---|
1389 | 1365 | .align = sizeof(unsigned int), |
---|
1390 | | - .get = s390_system_call_get, |
---|
| 1366 | + .regset_get = s390_system_call_get, |
---|
1391 | 1367 | .set = s390_system_call_set, |
---|
1392 | 1368 | }, |
---|
1393 | 1369 | { |
---|
.. | .. |
---|
1395 | 1371 | .n = 1, |
---|
1396 | 1372 | .size = sizeof(long), |
---|
1397 | 1373 | .align = sizeof(long), |
---|
1398 | | - .get = s390_last_break_get, |
---|
| 1374 | + .regset_get = s390_last_break_get, |
---|
1399 | 1375 | .set = s390_last_break_set, |
---|
1400 | 1376 | }, |
---|
1401 | 1377 | { |
---|
.. | .. |
---|
1403 | 1379 | .n = 1, |
---|
1404 | 1380 | .size = 256, |
---|
1405 | 1381 | .align = 1, |
---|
1406 | | - .get = s390_tdb_get, |
---|
| 1382 | + .regset_get = s390_tdb_get, |
---|
1407 | 1383 | .set = s390_tdb_set, |
---|
1408 | 1384 | }, |
---|
1409 | 1385 | { |
---|
.. | .. |
---|
1411 | 1387 | .n = __NUM_VXRS_LOW, |
---|
1412 | 1388 | .size = sizeof(__u64), |
---|
1413 | 1389 | .align = sizeof(__u64), |
---|
1414 | | - .get = s390_vxrs_low_get, |
---|
| 1390 | + .regset_get = s390_vxrs_low_get, |
---|
1415 | 1391 | .set = s390_vxrs_low_set, |
---|
1416 | 1392 | }, |
---|
1417 | 1393 | { |
---|
.. | .. |
---|
1419 | 1395 | .n = __NUM_VXRS_HIGH, |
---|
1420 | 1396 | .size = sizeof(__vector128), |
---|
1421 | 1397 | .align = sizeof(__vector128), |
---|
1422 | | - .get = s390_vxrs_high_get, |
---|
| 1398 | + .regset_get = s390_vxrs_high_get, |
---|
1423 | 1399 | .set = s390_vxrs_high_set, |
---|
1424 | 1400 | }, |
---|
1425 | 1401 | { |
---|
.. | .. |
---|
1427 | 1403 | .n = sizeof(struct gs_cb) / sizeof(__u64), |
---|
1428 | 1404 | .size = sizeof(__u64), |
---|
1429 | 1405 | .align = sizeof(__u64), |
---|
1430 | | - .get = s390_gs_cb_get, |
---|
| 1406 | + .regset_get = s390_gs_cb_get, |
---|
1431 | 1407 | .set = s390_gs_cb_set, |
---|
1432 | 1408 | }, |
---|
1433 | 1409 | { |
---|
.. | .. |
---|
1435 | 1411 | .n = sizeof(struct gs_cb) / sizeof(__u64), |
---|
1436 | 1412 | .size = sizeof(__u64), |
---|
1437 | 1413 | .align = sizeof(__u64), |
---|
1438 | | - .get = s390_gs_bc_get, |
---|
| 1414 | + .regset_get = s390_gs_bc_get, |
---|
1439 | 1415 | .set = s390_gs_bc_set, |
---|
1440 | 1416 | }, |
---|
1441 | 1417 | { |
---|
.. | .. |
---|
1443 | 1419 | .n = sizeof(struct runtime_instr_cb) / sizeof(__u64), |
---|
1444 | 1420 | .size = sizeof(__u64), |
---|
1445 | 1421 | .align = sizeof(__u64), |
---|
1446 | | - .get = s390_runtime_instr_get, |
---|
| 1422 | + .regset_get = s390_runtime_instr_get, |
---|
1447 | 1423 | .set = s390_runtime_instr_set, |
---|
1448 | 1424 | }, |
---|
1449 | 1425 | }; |
---|
1450 | 1426 | |
---|
1451 | 1427 | static const struct user_regset_view user_s390_view = { |
---|
1452 | | - .name = UTS_MACHINE, |
---|
| 1428 | + .name = "s390x", |
---|
1453 | 1429 | .e_machine = EM_S390, |
---|
1454 | 1430 | .regsets = s390_regsets, |
---|
1455 | 1431 | .n = ARRAY_SIZE(s390_regsets) |
---|
.. | .. |
---|
1458 | 1434 | #ifdef CONFIG_COMPAT |
---|
1459 | 1435 | static int s390_compat_regs_get(struct task_struct *target, |
---|
1460 | 1436 | const struct user_regset *regset, |
---|
1461 | | - unsigned int pos, unsigned int count, |
---|
1462 | | - void *kbuf, void __user *ubuf) |
---|
| 1437 | + struct membuf to) |
---|
1463 | 1438 | { |
---|
| 1439 | + unsigned n; |
---|
| 1440 | + |
---|
1464 | 1441 | if (target == current) |
---|
1465 | 1442 | save_access_regs(target->thread.acrs); |
---|
1466 | 1443 | |
---|
1467 | | - if (kbuf) { |
---|
1468 | | - compat_ulong_t *k = kbuf; |
---|
1469 | | - while (count > 0) { |
---|
1470 | | - *k++ = __peek_user_compat(target, pos); |
---|
1471 | | - count -= sizeof(*k); |
---|
1472 | | - pos += sizeof(*k); |
---|
1473 | | - } |
---|
1474 | | - } else { |
---|
1475 | | - compat_ulong_t __user *u = ubuf; |
---|
1476 | | - while (count > 0) { |
---|
1477 | | - if (__put_user(__peek_user_compat(target, pos), u++)) |
---|
1478 | | - return -EFAULT; |
---|
1479 | | - count -= sizeof(*u); |
---|
1480 | | - pos += sizeof(*u); |
---|
1481 | | - } |
---|
1482 | | - } |
---|
| 1444 | + for (n = 0; n < sizeof(s390_compat_regs); n += sizeof(compat_ulong_t)) |
---|
| 1445 | + membuf_store(&to, __peek_user_compat(target, n)); |
---|
1483 | 1446 | return 0; |
---|
1484 | 1447 | } |
---|
1485 | 1448 | |
---|
.. | .. |
---|
1521 | 1484 | |
---|
1522 | 1485 | static int s390_compat_regs_high_get(struct task_struct *target, |
---|
1523 | 1486 | const struct user_regset *regset, |
---|
1524 | | - unsigned int pos, unsigned int count, |
---|
1525 | | - void *kbuf, void __user *ubuf) |
---|
| 1487 | + struct membuf to) |
---|
1526 | 1488 | { |
---|
1527 | 1489 | compat_ulong_t *gprs_high; |
---|
| 1490 | + int i; |
---|
1528 | 1491 | |
---|
1529 | | - gprs_high = (compat_ulong_t *) |
---|
1530 | | - &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)]; |
---|
1531 | | - if (kbuf) { |
---|
1532 | | - compat_ulong_t *k = kbuf; |
---|
1533 | | - while (count > 0) { |
---|
1534 | | - *k++ = *gprs_high; |
---|
1535 | | - gprs_high += 2; |
---|
1536 | | - count -= sizeof(*k); |
---|
1537 | | - } |
---|
1538 | | - } else { |
---|
1539 | | - compat_ulong_t __user *u = ubuf; |
---|
1540 | | - while (count > 0) { |
---|
1541 | | - if (__put_user(*gprs_high, u++)) |
---|
1542 | | - return -EFAULT; |
---|
1543 | | - gprs_high += 2; |
---|
1544 | | - count -= sizeof(*u); |
---|
1545 | | - } |
---|
1546 | | - } |
---|
| 1492 | + gprs_high = (compat_ulong_t *)task_pt_regs(target)->gprs; |
---|
| 1493 | + for (i = 0; i < NUM_GPRS; i++, gprs_high += 2) |
---|
| 1494 | + membuf_store(&to, *gprs_high); |
---|
1547 | 1495 | return 0; |
---|
1548 | 1496 | } |
---|
1549 | 1497 | |
---|
.. | .. |
---|
1582 | 1530 | |
---|
1583 | 1531 | static int s390_compat_last_break_get(struct task_struct *target, |
---|
1584 | 1532 | const struct user_regset *regset, |
---|
1585 | | - unsigned int pos, unsigned int count, |
---|
1586 | | - void *kbuf, void __user *ubuf) |
---|
| 1533 | + struct membuf to) |
---|
1587 | 1534 | { |
---|
1588 | | - compat_ulong_t last_break; |
---|
| 1535 | + compat_ulong_t last_break = target->thread.last_break; |
---|
1589 | 1536 | |
---|
1590 | | - if (count > 0) { |
---|
1591 | | - last_break = target->thread.last_break; |
---|
1592 | | - if (kbuf) { |
---|
1593 | | - unsigned long *k = kbuf; |
---|
1594 | | - *k = last_break; |
---|
1595 | | - } else { |
---|
1596 | | - unsigned long __user *u = ubuf; |
---|
1597 | | - if (__put_user(last_break, u)) |
---|
1598 | | - return -EFAULT; |
---|
1599 | | - } |
---|
1600 | | - } |
---|
1601 | | - return 0; |
---|
| 1537 | + return membuf_store(&to, (unsigned long)last_break); |
---|
1602 | 1538 | } |
---|
1603 | 1539 | |
---|
1604 | 1540 | static int s390_compat_last_break_set(struct task_struct *target, |
---|
.. | .. |
---|
1615 | 1551 | .n = sizeof(s390_compat_regs) / sizeof(compat_long_t), |
---|
1616 | 1552 | .size = sizeof(compat_long_t), |
---|
1617 | 1553 | .align = sizeof(compat_long_t), |
---|
1618 | | - .get = s390_compat_regs_get, |
---|
| 1554 | + .regset_get = s390_compat_regs_get, |
---|
1619 | 1555 | .set = s390_compat_regs_set, |
---|
1620 | 1556 | }, |
---|
1621 | 1557 | { |
---|
.. | .. |
---|
1623 | 1559 | .n = sizeof(s390_fp_regs) / sizeof(compat_long_t), |
---|
1624 | 1560 | .size = sizeof(compat_long_t), |
---|
1625 | 1561 | .align = sizeof(compat_long_t), |
---|
1626 | | - .get = s390_fpregs_get, |
---|
| 1562 | + .regset_get = s390_fpregs_get, |
---|
1627 | 1563 | .set = s390_fpregs_set, |
---|
1628 | 1564 | }, |
---|
1629 | 1565 | { |
---|
.. | .. |
---|
1631 | 1567 | .n = 1, |
---|
1632 | 1568 | .size = sizeof(compat_uint_t), |
---|
1633 | 1569 | .align = sizeof(compat_uint_t), |
---|
1634 | | - .get = s390_system_call_get, |
---|
| 1570 | + .regset_get = s390_system_call_get, |
---|
1635 | 1571 | .set = s390_system_call_set, |
---|
1636 | 1572 | }, |
---|
1637 | 1573 | { |
---|
.. | .. |
---|
1639 | 1575 | .n = 1, |
---|
1640 | 1576 | .size = sizeof(long), |
---|
1641 | 1577 | .align = sizeof(long), |
---|
1642 | | - .get = s390_compat_last_break_get, |
---|
| 1578 | + .regset_get = s390_compat_last_break_get, |
---|
1643 | 1579 | .set = s390_compat_last_break_set, |
---|
1644 | 1580 | }, |
---|
1645 | 1581 | { |
---|
.. | .. |
---|
1647 | 1583 | .n = 1, |
---|
1648 | 1584 | .size = 256, |
---|
1649 | 1585 | .align = 1, |
---|
1650 | | - .get = s390_tdb_get, |
---|
| 1586 | + .regset_get = s390_tdb_get, |
---|
1651 | 1587 | .set = s390_tdb_set, |
---|
1652 | 1588 | }, |
---|
1653 | 1589 | { |
---|
.. | .. |
---|
1655 | 1591 | .n = __NUM_VXRS_LOW, |
---|
1656 | 1592 | .size = sizeof(__u64), |
---|
1657 | 1593 | .align = sizeof(__u64), |
---|
1658 | | - .get = s390_vxrs_low_get, |
---|
| 1594 | + .regset_get = s390_vxrs_low_get, |
---|
1659 | 1595 | .set = s390_vxrs_low_set, |
---|
1660 | 1596 | }, |
---|
1661 | 1597 | { |
---|
.. | .. |
---|
1663 | 1599 | .n = __NUM_VXRS_HIGH, |
---|
1664 | 1600 | .size = sizeof(__vector128), |
---|
1665 | 1601 | .align = sizeof(__vector128), |
---|
1666 | | - .get = s390_vxrs_high_get, |
---|
| 1602 | + .regset_get = s390_vxrs_high_get, |
---|
1667 | 1603 | .set = s390_vxrs_high_set, |
---|
1668 | 1604 | }, |
---|
1669 | 1605 | { |
---|
.. | .. |
---|
1671 | 1607 | .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t), |
---|
1672 | 1608 | .size = sizeof(compat_long_t), |
---|
1673 | 1609 | .align = sizeof(compat_long_t), |
---|
1674 | | - .get = s390_compat_regs_high_get, |
---|
| 1610 | + .regset_get = s390_compat_regs_high_get, |
---|
1675 | 1611 | .set = s390_compat_regs_high_set, |
---|
1676 | 1612 | }, |
---|
1677 | 1613 | { |
---|
.. | .. |
---|
1679 | 1615 | .n = sizeof(struct gs_cb) / sizeof(__u64), |
---|
1680 | 1616 | .size = sizeof(__u64), |
---|
1681 | 1617 | .align = sizeof(__u64), |
---|
1682 | | - .get = s390_gs_cb_get, |
---|
| 1618 | + .regset_get = s390_gs_cb_get, |
---|
1683 | 1619 | .set = s390_gs_cb_set, |
---|
1684 | 1620 | }, |
---|
1685 | 1621 | { |
---|
.. | .. |
---|
1687 | 1623 | .n = sizeof(struct gs_cb) / sizeof(__u64), |
---|
1688 | 1624 | .size = sizeof(__u64), |
---|
1689 | 1625 | .align = sizeof(__u64), |
---|
1690 | | - .get = s390_gs_bc_get, |
---|
| 1626 | + .regset_get = s390_gs_bc_get, |
---|
1691 | 1627 | .set = s390_gs_bc_set, |
---|
1692 | 1628 | }, |
---|
1693 | 1629 | { |
---|
.. | .. |
---|
1695 | 1631 | .n = sizeof(struct runtime_instr_cb) / sizeof(__u64), |
---|
1696 | 1632 | .size = sizeof(__u64), |
---|
1697 | 1633 | .align = sizeof(__u64), |
---|
1698 | | - .get = s390_runtime_instr_get, |
---|
| 1634 | + .regset_get = s390_runtime_instr_get, |
---|
1699 | 1635 | .set = s390_runtime_instr_set, |
---|
1700 | 1636 | }, |
---|
1701 | 1637 | }; |
---|