diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2010-10-25 10:10:37 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-10-25 10:10:19 -0400 |
commit | 1e54622e0403891b10f2105663e0f9dd595a1f17 (patch) | |
tree | 4d16341d7a3d0f3c46fcc275560a9206bccac07f /arch/s390/kernel/entry.S | |
parent | 84afdcee620b1640f2a145c07febae4ed68947f9 (diff) |
[S390] cleanup lowcore access from program checks
Read all required fields for program checks from the lowcore in the
first level interrupt handler in entry[64].S. If the context that
caused the fault was enabled for interrupts we can now re-enable the
irqs in entry[64].S.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 35 |
1 files changed, 10 insertions, 25 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index bea9ee37ac9d..adf25246f72e 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -72,25 +72,9 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
72 | l %r1,BASED(.Ltrace_irq_off_caller) | 72 | l %r1,BASED(.Ltrace_irq_off_caller) |
73 | basr %r14,%r1 | 73 | basr %r14,%r1 |
74 | .endm | 74 | .endm |
75 | |||
76 | .macro TRACE_IRQS_CHECK_ON | ||
77 | tm SP_PSW(%r15),0x03 # irqs enabled? | ||
78 | bz BASED(0f) | ||
79 | TRACE_IRQS_ON | ||
80 | 0: | ||
81 | .endm | ||
82 | |||
83 | .macro TRACE_IRQS_CHECK_OFF | ||
84 | tm SP_PSW(%r15),0x03 # irqs enabled? | ||
85 | bz BASED(0f) | ||
86 | TRACE_IRQS_OFF | ||
87 | 0: | ||
88 | .endm | ||
89 | #else | 75 | #else |
90 | #define TRACE_IRQS_ON | 76 | #define TRACE_IRQS_ON |
91 | #define TRACE_IRQS_OFF | 77 | #define TRACE_IRQS_OFF |
92 | #define TRACE_IRQS_CHECK_ON | ||
93 | #define TRACE_IRQS_CHECK_OFF | ||
94 | #endif | 78 | #endif |
95 | 79 | ||
96 | #ifdef CONFIG_LOCKDEP | 80 | #ifdef CONFIG_LOCKDEP |
@@ -198,6 +182,12 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
198 | lpsw \psworg # back to caller | 182 | lpsw \psworg # back to caller |
199 | .endm | 183 | .endm |
200 | 184 | ||
185 | .macro REENABLE_IRQS | ||
186 | mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) | ||
187 | ni __SF_EMPTY(%r15),0xbf | ||
188 | ssm __SF_EMPTY(%r15) | ||
189 | .endm | ||
190 | |||
201 | /* | 191 | /* |
202 | * Scheduler resume function, called by switch_to | 192 | * Scheduler resume function, called by switch_to |
203 | * gpr2 = (task_struct *) prev | 193 | * gpr2 = (task_struct *) prev |
@@ -440,13 +430,11 @@ kernel_execve: | |||
440 | br %r14 | 430 | br %r14 |
441 | # execve succeeded. | 431 | # execve succeeded. |
442 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts | 432 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts |
443 | TRACE_IRQS_OFF | ||
444 | l %r15,__LC_KERNEL_STACK # load ksp | 433 | l %r15,__LC_KERNEL_STACK # load ksp |
445 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 434 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
446 | l %r9,__LC_THREAD_INFO | 435 | l %r9,__LC_THREAD_INFO |
447 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs | 436 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs |
448 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 437 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
449 | TRACE_IRQS_ON | ||
450 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 438 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
451 | l %r1,BASED(.Lexecve_tail) | 439 | l %r1,BASED(.Lexecve_tail) |
452 | basr %r14,%r1 | 440 | basr %r14,%r1 |
@@ -483,9 +471,10 @@ pgm_check_handler: | |||
483 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 471 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
484 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 472 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
485 | pgm_no_vtime: | 473 | pgm_no_vtime: |
486 | TRACE_IRQS_CHECK_OFF | ||
487 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 474 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
488 | l %r3,__LC_PGM_ILC # load program interruption code | 475 | l %r3,__LC_PGM_ILC # load program interruption code |
476 | l %r4,__LC_TRANS_EXC_CODE | ||
477 | REENABLE_IRQS | ||
489 | la %r8,0x7f | 478 | la %r8,0x7f |
490 | nr %r8,%r3 | 479 | nr %r8,%r3 |
491 | pgm_do_call: | 480 | pgm_do_call: |
@@ -495,7 +484,6 @@ pgm_do_call: | |||
495 | la %r2,SP_PTREGS(%r15) # address of register-save area | 484 | la %r2,SP_PTREGS(%r15) # address of register-save area |
496 | basr %r14,%r7 # branch to interrupt-handler | 485 | basr %r14,%r7 # branch to interrupt-handler |
497 | pgm_exit: | 486 | pgm_exit: |
498 | TRACE_IRQS_CHECK_ON | ||
499 | b BASED(sysc_return) | 487 | b BASED(sysc_return) |
500 | 488 | ||
501 | # | 489 | # |
@@ -523,7 +511,6 @@ pgm_per_std: | |||
523 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 511 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
524 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 512 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
525 | pgm_no_vtime2: | 513 | pgm_no_vtime2: |
526 | TRACE_IRQS_CHECK_OFF | ||
527 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 514 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
528 | l %r1,__TI_task(%r9) | 515 | l %r1,__TI_task(%r9) |
529 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | 516 | tm SP_PSW+1(%r15),0x01 # kernel per event ? |
@@ -533,6 +520,8 @@ pgm_no_vtime2: | |||
533 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID | 520 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID |
534 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 521 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
535 | l %r3,__LC_PGM_ILC # load program interruption code | 522 | l %r3,__LC_PGM_ILC # load program interruption code |
523 | l %r4,__LC_TRANS_EXC_CODE | ||
524 | REENABLE_IRQS | ||
536 | la %r8,0x7f | 525 | la %r8,0x7f |
537 | nr %r8,%r3 # clear per-event-bit and ilc | 526 | nr %r8,%r3 # clear per-event-bit and ilc |
538 | be BASED(pgm_exit2) # only per or per+check ? | 527 | be BASED(pgm_exit2) # only per or per+check ? |
@@ -542,8 +531,6 @@ pgm_no_vtime2: | |||
542 | la %r2,SP_PTREGS(%r15) # address of register-save area | 531 | la %r2,SP_PTREGS(%r15) # address of register-save area |
543 | basr %r14,%r7 # branch to interrupt-handler | 532 | basr %r14,%r7 # branch to interrupt-handler |
544 | pgm_exit2: | 533 | pgm_exit2: |
545 | TRACE_IRQS_ON | ||
546 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | ||
547 | b BASED(sysc_return) | 534 | b BASED(sysc_return) |
548 | 535 | ||
549 | # | 536 | # |
@@ -557,13 +544,11 @@ pgm_svcper: | |||
557 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 544 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
558 | lh %r7,0x8a # get svc number from lowcore | 545 | lh %r7,0x8a # get svc number from lowcore |
559 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 546 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
560 | TRACE_IRQS_OFF | ||
561 | l %r8,__TI_task(%r9) | 547 | l %r8,__TI_task(%r9) |
562 | mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID | 548 | mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID |
563 | mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS | 549 | mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS |
564 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID | 550 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID |
565 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 551 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
566 | TRACE_IRQS_ON | ||
567 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 552 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
568 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | 553 | lm %r2,%r6,SP_R2(%r15) # load svc arguments |
569 | b BASED(sysc_do_svc) | 554 | b BASED(sysc_do_svc) |