diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-12-01 07:32:17 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-12-01 07:32:17 -0500 |
commit | b934069c991355d27a053a932591c77960f4e414 (patch) | |
tree | f76b362d58c877e8e73499fec71b5644c28cd7ad /arch/s390 | |
parent | 7c81878b34dd1b75dec5c8b68951d1439854d358 (diff) |
[S390] add missing .set function for NT_S390_LAST_BREAK regset
The last breaking event address is a read-only value, the regset misses the
.set function. If a PTRACE_SETREGSET is done for NT_S390_LAST_BREAK we
get an oops due to a branch to zero:
Kernel BUG at 0000000000000002 verbose debug info unavailable
illegal operation: 0001 #1 SMP
...
Call Trace:
(<0000000000158294> ptrace_regset+0x184/0x188)
<00000000001595b6> ptrace_request+0x37a/0x4fc
<0000000000109a78> arch_ptrace+0x108/0x1fc
<00000000001590d6> SyS_ptrace+0xaa/0x12c
<00000000005c7a42> sysc_noemu+0x16/0x1c
<000003fffd5ec10c> 0x3fffd5ec10c
Last Breaking-Event-Address:
<0000000000158242> ptrace_regset+0x132/0x188
Add a nop .set function to prevent the branch to zero.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: stable@kernel.org
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/ptrace.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 450931a45b68..f05649fd0547 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -905,6 +905,14 @@ static int s390_last_break_get(struct task_struct *target, | |||
905 | return 0; | 905 | return 0; |
906 | } | 906 | } |
907 | 907 | ||
908 | static int s390_last_break_set(struct task_struct *target, | ||
909 | const struct user_regset *regset, | ||
910 | unsigned int pos, unsigned int count, | ||
911 | const void *kbuf, const void __user *ubuf) | ||
912 | { | ||
913 | return 0; | ||
914 | } | ||
915 | |||
908 | #endif | 916 | #endif |
909 | 917 | ||
910 | static int s390_system_call_get(struct task_struct *target, | 918 | static int s390_system_call_get(struct task_struct *target, |
@@ -951,6 +959,7 @@ static const struct user_regset s390_regsets[] = { | |||
951 | .size = sizeof(long), | 959 | .size = sizeof(long), |
952 | .align = sizeof(long), | 960 | .align = sizeof(long), |
953 | .get = s390_last_break_get, | 961 | .get = s390_last_break_get, |
962 | .set = s390_last_break_set, | ||
954 | }, | 963 | }, |
955 | #endif | 964 | #endif |
956 | [REGSET_SYSTEM_CALL] = { | 965 | [REGSET_SYSTEM_CALL] = { |
@@ -1116,6 +1125,14 @@ static int s390_compat_last_break_get(struct task_struct *target, | |||
1116 | return 0; | 1125 | return 0; |
1117 | } | 1126 | } |
1118 | 1127 | ||
1128 | static int s390_compat_last_break_set(struct task_struct *target, | ||
1129 | const struct user_regset *regset, | ||
1130 | unsigned int pos, unsigned int count, | ||
1131 | const void *kbuf, const void __user *ubuf) | ||
1132 | { | ||
1133 | return 0; | ||
1134 | } | ||
1135 | |||
1119 | static const struct user_regset s390_compat_regsets[] = { | 1136 | static const struct user_regset s390_compat_regsets[] = { |
1120 | [REGSET_GENERAL] = { | 1137 | [REGSET_GENERAL] = { |
1121 | .core_note_type = NT_PRSTATUS, | 1138 | .core_note_type = NT_PRSTATUS, |
@@ -1139,6 +1156,7 @@ static const struct user_regset s390_compat_regsets[] = { | |||
1139 | .size = sizeof(long), | 1156 | .size = sizeof(long), |
1140 | .align = sizeof(long), | 1157 | .align = sizeof(long), |
1141 | .get = s390_compat_last_break_get, | 1158 | .get = s390_compat_last_break_get, |
1159 | .set = s390_compat_last_break_set, | ||
1142 | }, | 1160 | }, |
1143 | [REGSET_SYSTEM_CALL] = { | 1161 | [REGSET_SYSTEM_CALL] = { |
1144 | .core_note_type = NT_S390_SYSTEM_CALL, | 1162 | .core_note_type = NT_S390_SYSTEM_CALL, |