diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-04-20 07:54:11 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-04-21 06:38:56 -0400 |
commit | e525f8a6e696210d15f8b8277d4da12fc4add299 (patch) | |
tree | 6f8e78dd19d3f53c34a7656d097b832f8272c62e | |
parent | aa824e1340e79d26976c9f942add29edf612a67b (diff) |
s390/gs: add regset for the guarded storage broadcast control block
The guarded storage interface allows to register a control block for
each thread that is activated with the guarded storage broadcast event.
To retrieve the complete state of a process from the kernel a register
set for the stored broadcast control block is required.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/kernel/ptrace.c | 46 | ||||
-rw-r--r-- | include/uapi/linux/elf.h | 1 |
2 files changed, 47 insertions, 0 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index c933e255b5d5..488c5bb8dc77 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -1173,8 +1173,46 @@ static int s390_gs_cb_set(struct task_struct *target, | |||
1173 | 1173 | ||
1174 | if (!MACHINE_HAS_GS) | 1174 | if (!MACHINE_HAS_GS) |
1175 | return -ENODEV; | 1175 | return -ENODEV; |
1176 | if (!data) { | ||
1177 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
1178 | if (!data) | ||
1179 | return -ENOMEM; | ||
1180 | target->thread.gs_cb = data; | ||
1181 | } | ||
1182 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
1183 | data, 0, sizeof(struct gs_cb)); | ||
1184 | } | ||
1185 | |||
1186 | static int s390_gs_bc_get(struct task_struct *target, | ||
1187 | const struct user_regset *regset, | ||
1188 | unsigned int pos, unsigned int count, | ||
1189 | void *kbuf, void __user *ubuf) | ||
1190 | { | ||
1191 | struct gs_cb *data = target->thread.gs_bc_cb; | ||
1192 | |||
1193 | if (!MACHINE_HAS_GS) | ||
1194 | return -ENODEV; | ||
1176 | if (!data) | 1195 | if (!data) |
1177 | return -ENODATA; | 1196 | return -ENODATA; |
1197 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
1198 | data, 0, sizeof(struct gs_cb)); | ||
1199 | } | ||
1200 | |||
1201 | static int s390_gs_bc_set(struct task_struct *target, | ||
1202 | const struct user_regset *regset, | ||
1203 | unsigned int pos, unsigned int count, | ||
1204 | const void *kbuf, const void __user *ubuf) | ||
1205 | { | ||
1206 | struct gs_cb *data = target->thread.gs_bc_cb; | ||
1207 | |||
1208 | if (!MACHINE_HAS_GS) | ||
1209 | return -ENODEV; | ||
1210 | if (!data) { | ||
1211 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
1212 | if (!data) | ||
1213 | return -ENOMEM; | ||
1214 | target->thread.gs_bc_cb = data; | ||
1215 | } | ||
1178 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 1216 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
1179 | data, 0, sizeof(struct gs_cb)); | 1217 | data, 0, sizeof(struct gs_cb)); |
1180 | } | 1218 | } |
@@ -1244,6 +1282,14 @@ static const struct user_regset s390_regsets[] = { | |||
1244 | .get = s390_gs_cb_get, | 1282 | .get = s390_gs_cb_get, |
1245 | .set = s390_gs_cb_set, | 1283 | .set = s390_gs_cb_set, |
1246 | }, | 1284 | }, |
1285 | { | ||
1286 | .core_note_type = NT_S390_GS_BC, | ||
1287 | .n = sizeof(struct gs_cb) / sizeof(__u64), | ||
1288 | .size = sizeof(__u64), | ||
1289 | .align = sizeof(__u64), | ||
1290 | .get = s390_gs_bc_get, | ||
1291 | .set = s390_gs_bc_set, | ||
1292 | }, | ||
1247 | }; | 1293 | }; |
1248 | 1294 | ||
1249 | static const struct user_regset_view user_s390_view = { | 1295 | static const struct user_regset_view user_s390_view = { |
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index 8c6d3bdb9a00..176b6cb1008d 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h | |||
@@ -410,6 +410,7 @@ typedef struct elf64_shdr { | |||
410 | #define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 upper half */ | 410 | #define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 upper half */ |
411 | #define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */ | 411 | #define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */ |
412 | #define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */ | 412 | #define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */ |
413 | #define NT_S390_GS_BC 0x30c /* s390 guarded storage broadcast control block */ | ||
413 | #define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ | 414 | #define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ |
414 | #define NT_ARM_TLS 0x401 /* ARM TLS register */ | 415 | #define NT_ARM_TLS 0x401 /* ARM TLS register */ |
415 | #define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ | 416 | #define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ |