diff options
Diffstat (limited to 'arch/ia64/kernel/mca.c')
-rw-r--r-- | arch/ia64/kernel/mca.c | 104 |
1 files changed, 57 insertions, 47 deletions
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index d2877a7bfe2e..496ac7a99488 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -887,6 +887,60 @@ ia64_mca_modify_comm(const struct task_struct *previous_current) | |||
887 | memcpy(current->comm, comm, sizeof(current->comm)); | 887 | memcpy(current->comm, comm, sizeof(current->comm)); |
888 | } | 888 | } |
889 | 889 | ||
890 | static void | ||
891 | finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, | ||
892 | unsigned long *nat) | ||
893 | { | ||
894 | const u64 *bank; | ||
895 | |||
896 | /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use | ||
897 | * pmsa_{xip,xpsr,xfs} | ||
898 | */ | ||
899 | if (ia64_psr(regs)->ic) { | ||
900 | regs->cr_iip = ms->pmsa_iip; | ||
901 | regs->cr_ipsr = ms->pmsa_ipsr; | ||
902 | regs->cr_ifs = ms->pmsa_ifs; | ||
903 | } else { | ||
904 | regs->cr_iip = ms->pmsa_xip; | ||
905 | regs->cr_ipsr = ms->pmsa_xpsr; | ||
906 | regs->cr_ifs = ms->pmsa_xfs; | ||
907 | } | ||
908 | regs->pr = ms->pmsa_pr; | ||
909 | regs->b0 = ms->pmsa_br0; | ||
910 | regs->ar_rsc = ms->pmsa_rsc; | ||
911 | copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, ®s->r1, nat); | ||
912 | copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, ®s->r2, nat); | ||
913 | copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, ®s->r3, nat); | ||
914 | copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, ®s->r8, nat); | ||
915 | copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, ®s->r9, nat); | ||
916 | copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, ®s->r10, nat); | ||
917 | copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, ®s->r11, nat); | ||
918 | copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, ®s->r12, nat); | ||
919 | copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, ®s->r13, nat); | ||
920 | copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, ®s->r14, nat); | ||
921 | copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, ®s->r15, nat); | ||
922 | if (ia64_psr(regs)->bn) | ||
923 | bank = ms->pmsa_bank1_gr; | ||
924 | else | ||
925 | bank = ms->pmsa_bank0_gr; | ||
926 | copy_reg(&bank[16-16], ms->pmsa_nat_bits, ®s->r16, nat); | ||
927 | copy_reg(&bank[17-16], ms->pmsa_nat_bits, ®s->r17, nat); | ||
928 | copy_reg(&bank[18-16], ms->pmsa_nat_bits, ®s->r18, nat); | ||
929 | copy_reg(&bank[19-16], ms->pmsa_nat_bits, ®s->r19, nat); | ||
930 | copy_reg(&bank[20-16], ms->pmsa_nat_bits, ®s->r20, nat); | ||
931 | copy_reg(&bank[21-16], ms->pmsa_nat_bits, ®s->r21, nat); | ||
932 | copy_reg(&bank[22-16], ms->pmsa_nat_bits, ®s->r22, nat); | ||
933 | copy_reg(&bank[23-16], ms->pmsa_nat_bits, ®s->r23, nat); | ||
934 | copy_reg(&bank[24-16], ms->pmsa_nat_bits, ®s->r24, nat); | ||
935 | copy_reg(&bank[25-16], ms->pmsa_nat_bits, ®s->r25, nat); | ||
936 | copy_reg(&bank[26-16], ms->pmsa_nat_bits, ®s->r26, nat); | ||
937 | copy_reg(&bank[27-16], ms->pmsa_nat_bits, ®s->r27, nat); | ||
938 | copy_reg(&bank[28-16], ms->pmsa_nat_bits, ®s->r28, nat); | ||
939 | copy_reg(&bank[29-16], ms->pmsa_nat_bits, ®s->r29, nat); | ||
940 | copy_reg(&bank[30-16], ms->pmsa_nat_bits, ®s->r30, nat); | ||
941 | copy_reg(&bank[31-16], ms->pmsa_nat_bits, ®s->r31, nat); | ||
942 | } | ||
943 | |||
890 | /* On entry to this routine, we are running on the per cpu stack, see | 944 | /* On entry to this routine, we are running on the per cpu stack, see |
891 | * mca_asm.h. The original stack has not been touched by this event. Some of | 945 | * mca_asm.h. The original stack has not been touched by this event. Some of |
892 | * the original stack's registers will be in the RBS on this stack. This stack | 946 | * the original stack's registers will be in the RBS on this stack. This stack |
@@ -921,7 +975,6 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, | |||
921 | u64 r12 = ms->pmsa_gr[12-1], r13 = ms->pmsa_gr[13-1]; | 975 | u64 r12 = ms->pmsa_gr[12-1], r13 = ms->pmsa_gr[13-1]; |
922 | u64 ar_bspstore = regs->ar_bspstore; | 976 | u64 ar_bspstore = regs->ar_bspstore; |
923 | u64 ar_bsp = regs->ar_bspstore + (loadrs >> 16); | 977 | u64 ar_bsp = regs->ar_bspstore + (loadrs >> 16); |
924 | const u64 *bank; | ||
925 | const char *msg; | 978 | const char *msg; |
926 | int cpu = smp_processor_id(); | 979 | int cpu = smp_processor_id(); |
927 | 980 | ||
@@ -1024,54 +1077,9 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, | |||
1024 | p = (char *)r12 - sizeof(*regs); | 1077 | p = (char *)r12 - sizeof(*regs); |
1025 | old_regs = (struct pt_regs *)p; | 1078 | old_regs = (struct pt_regs *)p; |
1026 | memcpy(old_regs, regs, sizeof(*regs)); | 1079 | memcpy(old_regs, regs, sizeof(*regs)); |
1027 | /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use | ||
1028 | * pmsa_{xip,xpsr,xfs} | ||
1029 | */ | ||
1030 | if (ia64_psr(regs)->ic) { | ||
1031 | old_regs->cr_iip = ms->pmsa_iip; | ||
1032 | old_regs->cr_ipsr = ms->pmsa_ipsr; | ||
1033 | old_regs->cr_ifs = ms->pmsa_ifs; | ||
1034 | } else { | ||
1035 | old_regs->cr_iip = ms->pmsa_xip; | ||
1036 | old_regs->cr_ipsr = ms->pmsa_xpsr; | ||
1037 | old_regs->cr_ifs = ms->pmsa_xfs; | ||
1038 | } | ||
1039 | old_regs->pr = ms->pmsa_pr; | ||
1040 | old_regs->b0 = ms->pmsa_br0; | ||
1041 | old_regs->loadrs = loadrs; | 1080 | old_regs->loadrs = loadrs; |
1042 | old_regs->ar_rsc = ms->pmsa_rsc; | ||
1043 | old_unat = old_regs->ar_unat; | 1081 | old_unat = old_regs->ar_unat; |
1044 | copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, &old_regs->r1, &old_unat); | 1082 | finish_pt_regs(old_regs, ms, &old_unat); |
1045 | copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, &old_regs->r2, &old_unat); | ||
1046 | copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, &old_regs->r3, &old_unat); | ||
1047 | copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, &old_regs->r8, &old_unat); | ||
1048 | copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, &old_regs->r9, &old_unat); | ||
1049 | copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, &old_regs->r10, &old_unat); | ||
1050 | copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, &old_regs->r11, &old_unat); | ||
1051 | copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, &old_regs->r12, &old_unat); | ||
1052 | copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, &old_regs->r13, &old_unat); | ||
1053 | copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, &old_regs->r14, &old_unat); | ||
1054 | copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, &old_regs->r15, &old_unat); | ||
1055 | if (ia64_psr(old_regs)->bn) | ||
1056 | bank = ms->pmsa_bank1_gr; | ||
1057 | else | ||
1058 | bank = ms->pmsa_bank0_gr; | ||
1059 | copy_reg(&bank[16-16], ms->pmsa_nat_bits, &old_regs->r16, &old_unat); | ||
1060 | copy_reg(&bank[17-16], ms->pmsa_nat_bits, &old_regs->r17, &old_unat); | ||
1061 | copy_reg(&bank[18-16], ms->pmsa_nat_bits, &old_regs->r18, &old_unat); | ||
1062 | copy_reg(&bank[19-16], ms->pmsa_nat_bits, &old_regs->r19, &old_unat); | ||
1063 | copy_reg(&bank[20-16], ms->pmsa_nat_bits, &old_regs->r20, &old_unat); | ||
1064 | copy_reg(&bank[21-16], ms->pmsa_nat_bits, &old_regs->r21, &old_unat); | ||
1065 | copy_reg(&bank[22-16], ms->pmsa_nat_bits, &old_regs->r22, &old_unat); | ||
1066 | copy_reg(&bank[23-16], ms->pmsa_nat_bits, &old_regs->r23, &old_unat); | ||
1067 | copy_reg(&bank[24-16], ms->pmsa_nat_bits, &old_regs->r24, &old_unat); | ||
1068 | copy_reg(&bank[25-16], ms->pmsa_nat_bits, &old_regs->r25, &old_unat); | ||
1069 | copy_reg(&bank[26-16], ms->pmsa_nat_bits, &old_regs->r26, &old_unat); | ||
1070 | copy_reg(&bank[27-16], ms->pmsa_nat_bits, &old_regs->r27, &old_unat); | ||
1071 | copy_reg(&bank[28-16], ms->pmsa_nat_bits, &old_regs->r28, &old_unat); | ||
1072 | copy_reg(&bank[29-16], ms->pmsa_nat_bits, &old_regs->r29, &old_unat); | ||
1073 | copy_reg(&bank[30-16], ms->pmsa_nat_bits, &old_regs->r30, &old_unat); | ||
1074 | copy_reg(&bank[31-16], ms->pmsa_nat_bits, &old_regs->r31, &old_unat); | ||
1075 | 1083 | ||
1076 | /* Next stack a struct switch_stack. mca_asm.S built a partial | 1084 | /* Next stack a struct switch_stack. mca_asm.S built a partial |
1077 | * switch_stack, copy it and fill in the blanks using pt_regs and | 1085 | * switch_stack, copy it and fill in the blanks using pt_regs and |
@@ -1141,6 +1149,8 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, | |||
1141 | no_mod: | 1149 | no_mod: |
1142 | mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", | 1150 | mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", |
1143 | smp_processor_id(), type, msg); | 1151 | smp_processor_id(), type, msg); |
1152 | old_unat = regs->ar_unat; | ||
1153 | finish_pt_regs(regs, ms, &old_unat); | ||
1144 | return previous_current; | 1154 | return previous_current; |
1145 | } | 1155 | } |
1146 | 1156 | ||