diff options
Diffstat (limited to 'arch/ia64/kernel/ivt.S')
-rw-r--r-- | arch/ia64/kernel/ivt.S | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 34f44d8be00d..6678c49daba3 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S | |||
@@ -805,8 +805,13 @@ ENTRY(break_fault) | |||
805 | 805 | ||
806 | (p8) adds r28=16,r28 // A switch cr.iip to next bundle | 806 | (p8) adds r28=16,r28 // A switch cr.iip to next bundle |
807 | (p9) adds r8=1,r8 // A increment ei to next slot | 807 | (p9) adds r8=1,r8 // A increment ei to next slot |
808 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
809 | ;; | ||
810 | mov b6=r30 // I0 setup syscall handler branch reg early | ||
811 | #else | ||
808 | nop.i 0 | 812 | nop.i 0 |
809 | ;; | 813 | ;; |
814 | #endif | ||
810 | 815 | ||
811 | mov.m r25=ar.unat // M2 (5 cyc) | 816 | mov.m r25=ar.unat // M2 (5 cyc) |
812 | dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr | 817 | dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr |
@@ -817,7 +822,11 @@ ENTRY(break_fault) | |||
817 | // | 822 | // |
818 | /////////////////////////////////////////////////////////////////////// | 823 | /////////////////////////////////////////////////////////////////////// |
819 | st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag | 824 | st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag |
825 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
826 | mov.m r30=ar.itc // M get cycle for accounting | ||
827 | #else | ||
820 | mov b6=r30 // I0 setup syscall handler branch reg early | 828 | mov b6=r30 // I0 setup syscall handler branch reg early |
829 | #endif | ||
821 | cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? | 830 | cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? |
822 | 831 | ||
823 | and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit | 832 | and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit |
@@ -829,6 +838,30 @@ ENTRY(break_fault) | |||
829 | cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? | 838 | cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? |
830 | br.call.sptk.many b7=ia64_syscall_setup // B | 839 | br.call.sptk.many b7=ia64_syscall_setup // B |
831 | 1: | 840 | 1: |
841 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
842 | // mov.m r30=ar.itc is called in advance, and r13 is current | ||
843 | add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 // A | ||
844 | add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 // A | ||
845 | (pKStk) br.cond.spnt .skip_accounting // B unlikely skip | ||
846 | ;; | ||
847 | ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP // M get last stamp | ||
848 | ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE // M time at leave | ||
849 | ;; | ||
850 | ld8 r20=[r16],TI_AC_STAMP-TI_AC_STIME // M cumulated stime | ||
851 | ld8 r21=[r17] // M cumulated utime | ||
852 | sub r22=r19,r18 // A stime before leave | ||
853 | ;; | ||
854 | st8 [r16]=r30,TI_AC_STIME-TI_AC_STAMP // M update stamp | ||
855 | sub r18=r30,r19 // A elapsed time in user | ||
856 | ;; | ||
857 | add r20=r20,r22 // A sum stime | ||
858 | add r21=r21,r18 // A sum utime | ||
859 | ;; | ||
860 | st8 [r16]=r20 // M update stime | ||
861 | st8 [r17]=r21 // M update utime | ||
862 | ;; | ||
863 | .skip_accounting: | ||
864 | #endif | ||
832 | mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 | 865 | mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 |
833 | nop 0 | 866 | nop 0 |
834 | bsw.1 // B (6 cyc) regs are saved, switch to bank 1 | 867 | bsw.1 // B (6 cyc) regs are saved, switch to bank 1 |
@@ -928,6 +961,7 @@ END(interrupt) | |||
928 | * - r27: saved ar.rsc | 961 | * - r27: saved ar.rsc |
929 | * - r28: saved cr.iip | 962 | * - r28: saved cr.iip |
930 | * - r29: saved cr.ipsr | 963 | * - r29: saved cr.ipsr |
964 | * - r30: ar.itc for accounting (don't touch) | ||
931 | * - r31: saved pr | 965 | * - r31: saved pr |
932 | * - b0: original contents (to be saved) | 966 | * - b0: original contents (to be saved) |
933 | * On exit: | 967 | * On exit: |
@@ -1090,6 +1124,41 @@ END(dispatch_illegal_op_fault) | |||
1090 | DBG_FAULT(16) | 1124 | DBG_FAULT(16) |
1091 | FAULT(16) | 1125 | FAULT(16) |
1092 | 1126 | ||
1127 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
1128 | /* | ||
1129 | * There is no particular reason for this code to be here, other than | ||
1130 | * that there happens to be space here that would go unused otherwise. | ||
1131 | * If this fault ever gets "unreserved", simply moved the following | ||
1132 | * code to a more suitable spot... | ||
1133 | * | ||
1134 | * account_sys_enter is called from SAVE_MIN* macros if accounting is | ||
1135 | * enabled and if the macro is entered from user mode. | ||
1136 | */ | ||
1137 | ENTRY(account_sys_enter) | ||
1138 | // mov.m r20=ar.itc is called in advance, and r13 is current | ||
1139 | add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 | ||
1140 | add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 | ||
1141 | ;; | ||
1142 | ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP // time at last check in kernel | ||
1143 | ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE // time at left from kernel | ||
1144 | ;; | ||
1145 | ld8 r23=[r16],TI_AC_STAMP-TI_AC_STIME // cumulated stime | ||
1146 | ld8 r21=[r17] // cumulated utime | ||
1147 | sub r22=r19,r18 // stime before leave kernel | ||
1148 | ;; | ||
1149 | st8 [r16]=r20,TI_AC_STIME-TI_AC_STAMP // update stamp | ||
1150 | sub r18=r20,r19 // elapsed time in user mode | ||
1151 | ;; | ||
1152 | add r23=r23,r22 // sum stime | ||
1153 | add r21=r21,r18 // sum utime | ||
1154 | ;; | ||
1155 | st8 [r16]=r23 // update stime | ||
1156 | st8 [r17]=r21 // update utime | ||
1157 | ;; | ||
1158 | br.ret.sptk.many rp | ||
1159 | END(account_sys_enter) | ||
1160 | #endif | ||
1161 | |||
1093 | .org ia64_ivt+0x4400 | 1162 | .org ia64_ivt+0x4400 |
1094 | ///////////////////////////////////////////////////////////////////////////////////////// | 1163 | ///////////////////////////////////////////////////////////////////////////////////////// |
1095 | // 0x4400 Entry 17 (size 64 bundles) Reserved | 1164 | // 0x4400 Entry 17 (size 64 bundles) Reserved |