aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/pgtable.h8
-rw-r--r--arch/s390/kernel/ptrace.c30
-rw-r--r--arch/s390/kernel/setup.c2
-rw-r--r--arch/s390/kernel/signal.c8
4 files changed, 26 insertions, 22 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 524d23b8610c..4f289ff0b7fe 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -599,10 +599,10 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
599 skey = page_get_storage_key(address); 599 skey = page_get_storage_key(address);
600 bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); 600 bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
601 /* Clear page changed & referenced bit in the storage key */ 601 /* Clear page changed & referenced bit in the storage key */
602 if (bits) { 602 if (bits & _PAGE_CHANGED)
603 skey ^= bits; 603 page_set_storage_key(address, skey ^ bits, 1);
604 page_set_storage_key(address, skey, 1); 604 else if (bits)
605 } 605 page_reset_referenced(address);
606 /* Transfer page changed & referenced bit to guest bits in pgste */ 606 /* Transfer page changed & referenced bit to guest bits in pgste */
607 pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */ 607 pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */
608 /* Get host changed & referenced bits from pgste */ 608 /* Get host changed & referenced bits from pgste */
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 450931a45b68..573bc29551ef 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -296,13 +296,6 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
296 ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA)))) 296 ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))))
297 /* Invalid psw mask. */ 297 /* Invalid psw mask. */
298 return -EINVAL; 298 return -EINVAL;
299 if (addr == (addr_t) &dummy->regs.psw.addr)
300 /*
301 * The debugger changed the instruction address,
302 * reset system call restart, see signal.c:do_signal
303 */
304 task_thread_info(child)->system_call = 0;
305
306 *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; 299 *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
307 300
308 } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { 301 } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
@@ -614,11 +607,6 @@ static int __poke_user_compat(struct task_struct *child,
614 /* Transfer 31 bit amode bit to psw mask. */ 607 /* Transfer 31 bit amode bit to psw mask. */
615 regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) | 608 regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) |
616 (__u64)(tmp & PSW32_ADDR_AMODE); 609 (__u64)(tmp & PSW32_ADDR_AMODE);
617 /*
618 * The debugger changed the instruction address,
619 * reset system call restart, see signal.c:do_signal
620 */
621 task_thread_info(child)->system_call = 0;
622 } else { 610 } else {
623 /* gpr 0-15 */ 611 /* gpr 0-15 */
624 *(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp; 612 *(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
@@ -905,6 +893,14 @@ static int s390_last_break_get(struct task_struct *target,
905 return 0; 893 return 0;
906} 894}
907 895
896static int s390_last_break_set(struct task_struct *target,
897 const struct user_regset *regset,
898 unsigned int pos, unsigned int count,
899 const void *kbuf, const void __user *ubuf)
900{
901 return 0;
902}
903
908#endif 904#endif
909 905
910static int s390_system_call_get(struct task_struct *target, 906static int s390_system_call_get(struct task_struct *target,
@@ -951,6 +947,7 @@ static const struct user_regset s390_regsets[] = {
951 .size = sizeof(long), 947 .size = sizeof(long),
952 .align = sizeof(long), 948 .align = sizeof(long),
953 .get = s390_last_break_get, 949 .get = s390_last_break_get,
950 .set = s390_last_break_set,
954 }, 951 },
955#endif 952#endif
956 [REGSET_SYSTEM_CALL] = { 953 [REGSET_SYSTEM_CALL] = {
@@ -1116,6 +1113,14 @@ static int s390_compat_last_break_get(struct task_struct *target,
1116 return 0; 1113 return 0;
1117} 1114}
1118 1115
1116static int s390_compat_last_break_set(struct task_struct *target,
1117 const struct user_regset *regset,
1118 unsigned int pos, unsigned int count,
1119 const void *kbuf, const void __user *ubuf)
1120{
1121 return 0;
1122}
1123
1119static const struct user_regset s390_compat_regsets[] = { 1124static const struct user_regset s390_compat_regsets[] = {
1120 [REGSET_GENERAL] = { 1125 [REGSET_GENERAL] = {
1121 .core_note_type = NT_PRSTATUS, 1126 .core_note_type = NT_PRSTATUS,
@@ -1139,6 +1144,7 @@ static const struct user_regset s390_compat_regsets[] = {
1139 .size = sizeof(long), 1144 .size = sizeof(long),
1140 .align = sizeof(long), 1145 .align = sizeof(long),
1141 .get = s390_compat_last_break_get, 1146 .get = s390_compat_last_break_get,
1147 .set = s390_compat_last_break_set,
1142 }, 1148 },
1143 [REGSET_SYSTEM_CALL] = { 1149 [REGSET_SYSTEM_CALL] = {
1144 .core_note_type = NT_S390_SYSTEM_CALL, 1150 .core_note_type = NT_S390_SYSTEM_CALL,
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index e58a462949b1..e54c4ff8abaa 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -579,7 +579,7 @@ static unsigned long __init find_crash_base(unsigned long crash_size,
579 *msg = "first memory chunk must be at least crashkernel size"; 579 *msg = "first memory chunk must be at least crashkernel size";
580 return 0; 580 return 0;
581 } 581 }
582 if (is_kdump_kernel() && (crash_size == OLDMEM_SIZE)) 582 if (OLDMEM_BASE && crash_size == OLDMEM_SIZE)
583 return OLDMEM_BASE; 583 return OLDMEM_BASE;
584 584
585 for (i = MEMORY_CHUNKS - 1; i >= 0; i--) { 585 for (i = MEMORY_CHUNKS - 1; i >= 0; i--) {
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 05a85bc14c98..7f6f9f354545 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -460,9 +460,9 @@ void do_signal(struct pt_regs *regs)
460 regs->svc_code >> 16); 460 regs->svc_code >> 16);
461 break; 461 break;
462 } 462 }
463 /* No longer in a system call */
464 clear_thread_flag(TIF_SYSCALL);
465 } 463 }
464 /* No longer in a system call */
465 clear_thread_flag(TIF_SYSCALL);
466 466
467 if ((is_compat_task() ? 467 if ((is_compat_task() ?
468 handle_signal32(signr, &ka, &info, oldset, regs) : 468 handle_signal32(signr, &ka, &info, oldset, regs) :
@@ -486,6 +486,7 @@ void do_signal(struct pt_regs *regs)
486 } 486 }
487 487
488 /* No handlers present - check for system call restart */ 488 /* No handlers present - check for system call restart */
489 clear_thread_flag(TIF_SYSCALL);
489 if (current_thread_info()->system_call) { 490 if (current_thread_info()->system_call) {
490 regs->svc_code = current_thread_info()->system_call; 491 regs->svc_code = current_thread_info()->system_call;
491 switch (regs->gprs[2]) { 492 switch (regs->gprs[2]) {
@@ -500,9 +501,6 @@ void do_signal(struct pt_regs *regs)
500 regs->gprs[2] = regs->orig_gpr2; 501 regs->gprs[2] = regs->orig_gpr2;
501 set_thread_flag(TIF_SYSCALL); 502 set_thread_flag(TIF_SYSCALL);
502 break; 503 break;
503 default:
504 clear_thread_flag(TIF_SYSCALL);
505 break;
506 } 504 }
507 } 505 }
508 506