diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-12-01 07:32:17 -0500 |
---|---|---|
committer | Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com> | 2011-12-12 08:07:09 -0500 |
commit | c28cee94593042f422259d76f8cdd4ecf447a271 (patch) | |
tree | 369ae1baffb422d095433e9cbef5da3223646190 /arch/s390 | |
parent | acfaab14513e31da85996af542e9e0cfe40308b7 (diff) |
add missing .set function for NT_S390_LAST_BREAK regset
BugLink: http://bugs.launchpad.net/bugs/902312
commit b934069c991355d27a053a932591c77960f4e414 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
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 ae0e14b8880..5804cfa7cba 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -897,6 +897,14 @@ static int s390_last_break_get(struct task_struct *target, | |||
897 | return 0; | 897 | return 0; |
898 | } | 898 | } |
899 | 899 | ||
900 | static int s390_last_break_set(struct task_struct *target, | ||
901 | const struct user_regset *regset, | ||
902 | unsigned int pos, unsigned int count, | ||
903 | const void *kbuf, const void __user *ubuf) | ||
904 | { | ||
905 | return 0; | ||
906 | } | ||
907 | |||
900 | #endif | 908 | #endif |
901 | 909 | ||
902 | static const struct user_regset s390_regsets[] = { | 910 | static const struct user_regset s390_regsets[] = { |
@@ -923,6 +931,7 @@ static const struct user_regset s390_regsets[] = { | |||
923 | .size = sizeof(long), | 931 | .size = sizeof(long), |
924 | .align = sizeof(long), | 932 | .align = sizeof(long), |
925 | .get = s390_last_break_get, | 933 | .get = s390_last_break_get, |
934 | .set = s390_last_break_set, | ||
926 | }, | 935 | }, |
927 | #endif | 936 | #endif |
928 | }; | 937 | }; |
@@ -1080,6 +1089,14 @@ static int s390_compat_last_break_get(struct task_struct *target, | |||
1080 | return 0; | 1089 | return 0; |
1081 | } | 1090 | } |
1082 | 1091 | ||
1092 | static int s390_compat_last_break_set(struct task_struct *target, | ||
1093 | const struct user_regset *regset, | ||
1094 | unsigned int pos, unsigned int count, | ||
1095 | const void *kbuf, const void __user *ubuf) | ||
1096 | { | ||
1097 | return 0; | ||
1098 | } | ||
1099 | |||
1083 | static const struct user_regset s390_compat_regsets[] = { | 1100 | static const struct user_regset s390_compat_regsets[] = { |
1084 | [REGSET_GENERAL] = { | 1101 | [REGSET_GENERAL] = { |
1085 | .core_note_type = NT_PRSTATUS, | 1102 | .core_note_type = NT_PRSTATUS, |
@@ -1103,6 +1120,7 @@ static const struct user_regset s390_compat_regsets[] = { | |||
1103 | .size = sizeof(long), | 1120 | .size = sizeof(long), |
1104 | .align = sizeof(long), | 1121 | .align = sizeof(long), |
1105 | .get = s390_compat_last_break_get, | 1122 | .get = s390_compat_last_break_get, |
1123 | .set = s390_compat_last_break_set, | ||
1106 | }, | 1124 | }, |
1107 | [REGSET_GENERAL_EXTENDED] = { | 1125 | [REGSET_GENERAL_EXTENDED] = { |
1108 | .core_note_type = NT_S390_HIGH_GPRS, | 1126 | .core_note_type = NT_S390_HIGH_GPRS, |