aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2017-05-02 07:36:00 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-05-03 03:08:57 -0400
commit07a63cbe8bcb6ba72fb989dcab1ec55ec6c36c7e (patch)
treee7ef1fae73975159ed7886988db715af73e73d49
parent89c9fea3c8034cdb2fd745f551cde0b507fd6893 (diff)
s390/cputime: fix incorrect system time
git commit c5328901aa1db134 "[S390] entry[64].S improvements" removed the update of the exit_timer lowcore field from the critical section cleanup of the .Lsysc_restore/.Lsysc_done and .Lio_restore/.Lio_done blocks. If the PSW is updated by the critical section cleanup to point to user space again, the interrupt entry code will do a vtime calculation after the cleanup completed with an exit_timer value which has *not* been updated. Due to this incorrect system time deltas are calculated. If an interrupt occured with an old PSW between .Lsysc_restore/.Lsysc_done or .Lio_restore/.Lio_done update __LC_EXIT_TIMER with the system entry time of the interrupt. Cc: stable@vger.kernel.org # 3.3+ Tested-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/entry.S21
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index a5f5d3bb3dbc..e408d9cc5b96 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -312,6 +312,7 @@ ENTRY(system_call)
312 lg %r14,__LC_VDSO_PER_CPU 312 lg %r14,__LC_VDSO_PER_CPU
313 lmg %r0,%r10,__PT_R0(%r11) 313 lmg %r0,%r10,__PT_R0(%r11)
314 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 314 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
315.Lsysc_exit_timer:
315 stpt __LC_EXIT_TIMER 316 stpt __LC_EXIT_TIMER
316 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 317 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
317 lmg %r11,%r15,__PT_R11(%r11) 318 lmg %r11,%r15,__PT_R11(%r11)
@@ -623,6 +624,7 @@ ENTRY(io_int_handler)
623 lg %r14,__LC_VDSO_PER_CPU 624 lg %r14,__LC_VDSO_PER_CPU
624 lmg %r0,%r10,__PT_R0(%r11) 625 lmg %r0,%r10,__PT_R0(%r11)
625 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 626 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
627.Lio_exit_timer:
626 stpt __LC_EXIT_TIMER 628 stpt __LC_EXIT_TIMER
627 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 629 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
628 lmg %r11,%r15,__PT_R11(%r11) 630 lmg %r11,%r15,__PT_R11(%r11)
@@ -1174,15 +1176,23 @@ cleanup_critical:
1174 br %r14 1176 br %r14
1175 1177
1176.Lcleanup_sysc_restore: 1178.Lcleanup_sysc_restore:
1179 # check if stpt has been executed
1177 clg %r9,BASED(.Lcleanup_sysc_restore_insn) 1180 clg %r9,BASED(.Lcleanup_sysc_restore_insn)
1181 jh 0f
1182 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
1183 cghi %r11,__LC_SAVE_AREA_ASYNC
1178 je 0f 1184 je 0f
1185 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
11860: clg %r9,BASED(.Lcleanup_sysc_restore_insn+8)
1187 je 1f
1179 lg %r9,24(%r11) # get saved pointer to pt_regs 1188 lg %r9,24(%r11) # get saved pointer to pt_regs
1180 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) 1189 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1181 mvc 0(64,%r11),__PT_R8(%r9) 1190 mvc 0(64,%r11),__PT_R8(%r9)
1182 lmg %r0,%r7,__PT_R0(%r9) 1191 lmg %r0,%r7,__PT_R0(%r9)
11830: lmg %r8,%r9,__LC_RETURN_PSW 11921: lmg %r8,%r9,__LC_RETURN_PSW
1184 br %r14 1193 br %r14
1185.Lcleanup_sysc_restore_insn: 1194.Lcleanup_sysc_restore_insn:
1195 .quad .Lsysc_exit_timer
1186 .quad .Lsysc_done - 4 1196 .quad .Lsysc_done - 4
1187 1197
1188.Lcleanup_io_tif: 1198.Lcleanup_io_tif:
@@ -1190,15 +1200,20 @@ cleanup_critical:
1190 br %r14 1200 br %r14
1191 1201
1192.Lcleanup_io_restore: 1202.Lcleanup_io_restore:
1203 # check if stpt has been executed
1193 clg %r9,BASED(.Lcleanup_io_restore_insn) 1204 clg %r9,BASED(.Lcleanup_io_restore_insn)
1194 je 0f 1205 jh 0f
1206 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
12070: clg %r9,BASED(.Lcleanup_io_restore_insn+8)
1208 je 1f
1195 lg %r9,24(%r11) # get saved r11 pointer to pt_regs 1209 lg %r9,24(%r11) # get saved r11 pointer to pt_regs
1196 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) 1210 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1197 mvc 0(64,%r11),__PT_R8(%r9) 1211 mvc 0(64,%r11),__PT_R8(%r9)
1198 lmg %r0,%r7,__PT_R0(%r9) 1212 lmg %r0,%r7,__PT_R0(%r9)
11990: lmg %r8,%r9,__LC_RETURN_PSW 12131: lmg %r8,%r9,__LC_RETURN_PSW
1200 br %r14 1214 br %r14
1201.Lcleanup_io_restore_insn: 1215.Lcleanup_io_restore_insn:
1216 .quad .Lio_exit_timer
1202 .quad .Lio_done - 4 1217 .quad .Lio_done - 4
1203 1218
1204.Lcleanup_idle: 1219.Lcleanup_idle: