diff options
Diffstat (limited to 'arch/s390/kernel/ptrace.c')
-rw-r--r-- | arch/s390/kernel/ptrace.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index a8738676b26c..653c6a178740 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -57,6 +57,7 @@ | |||
57 | enum s390_regset { | 57 | enum s390_regset { |
58 | REGSET_GENERAL, | 58 | REGSET_GENERAL, |
59 | REGSET_FP, | 59 | REGSET_FP, |
60 | REGSET_GENERAL_EXTENDED, | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | static void | 63 | static void |
@@ -879,6 +880,67 @@ static int s390_compat_regs_set(struct task_struct *target, | |||
879 | return rc; | 880 | return rc; |
880 | } | 881 | } |
881 | 882 | ||
883 | static int s390_compat_regs_high_get(struct task_struct *target, | ||
884 | const struct user_regset *regset, | ||
885 | unsigned int pos, unsigned int count, | ||
886 | void *kbuf, void __user *ubuf) | ||
887 | { | ||
888 | compat_ulong_t *gprs_high; | ||
889 | |||
890 | gprs_high = (compat_ulong_t *) | ||
891 | &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)]; | ||
892 | if (kbuf) { | ||
893 | compat_ulong_t *k = kbuf; | ||
894 | while (count > 0) { | ||
895 | *k++ = *gprs_high; | ||
896 | gprs_high += 2; | ||
897 | count -= sizeof(*k); | ||
898 | } | ||
899 | } else { | ||
900 | compat_ulong_t __user *u = ubuf; | ||
901 | while (count > 0) { | ||
902 | if (__put_user(*gprs_high, u++)) | ||
903 | return -EFAULT; | ||
904 | gprs_high += 2; | ||
905 | count -= sizeof(*u); | ||
906 | } | ||
907 | } | ||
908 | return 0; | ||
909 | } | ||
910 | |||
911 | static int s390_compat_regs_high_set(struct task_struct *target, | ||
912 | const struct user_regset *regset, | ||
913 | unsigned int pos, unsigned int count, | ||
914 | const void *kbuf, const void __user *ubuf) | ||
915 | { | ||
916 | compat_ulong_t *gprs_high; | ||
917 | int rc = 0; | ||
918 | |||
919 | gprs_high = (compat_ulong_t *) | ||
920 | &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)]; | ||
921 | if (kbuf) { | ||
922 | const compat_ulong_t *k = kbuf; | ||
923 | while (count > 0) { | ||
924 | *gprs_high = *k++; | ||
925 | *gprs_high += 2; | ||
926 | count -= sizeof(*k); | ||
927 | } | ||
928 | } else { | ||
929 | const compat_ulong_t __user *u = ubuf; | ||
930 | while (count > 0 && !rc) { | ||
931 | unsigned long word; | ||
932 | rc = __get_user(word, u++); | ||
933 | if (rc) | ||
934 | break; | ||
935 | *gprs_high = word; | ||
936 | *gprs_high += 2; | ||
937 | count -= sizeof(*u); | ||
938 | } | ||
939 | } | ||
940 | |||
941 | return rc; | ||
942 | } | ||
943 | |||
882 | static const struct user_regset s390_compat_regsets[] = { | 944 | static const struct user_regset s390_compat_regsets[] = { |
883 | [REGSET_GENERAL] = { | 945 | [REGSET_GENERAL] = { |
884 | .core_note_type = NT_PRSTATUS, | 946 | .core_note_type = NT_PRSTATUS, |
@@ -896,6 +958,14 @@ static const struct user_regset s390_compat_regsets[] = { | |||
896 | .get = s390_fpregs_get, | 958 | .get = s390_fpregs_get, |
897 | .set = s390_fpregs_set, | 959 | .set = s390_fpregs_set, |
898 | }, | 960 | }, |
961 | [REGSET_GENERAL_EXTENDED] = { | ||
962 | .core_note_type = NT_PRXSTATUS, | ||
963 | .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t), | ||
964 | .size = sizeof(compat_long_t), | ||
965 | .align = sizeof(compat_long_t), | ||
966 | .get = s390_compat_regs_high_get, | ||
967 | .set = s390_compat_regs_high_set, | ||
968 | }, | ||
899 | }; | 969 | }; |
900 | 970 | ||
901 | static const struct user_regset_view user_s390_compat_view = { | 971 | static const struct user_regset_view user_s390_compat_view = { |