diff options
Diffstat (limited to 'arch/ia64/kernel/mca.c')
-rw-r--r-- | arch/ia64/kernel/mca.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 496ac7a99488..a0220dc5ff42 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -85,6 +85,7 @@ | |||
85 | #include <linux/cpumask.h> | 85 | #include <linux/cpumask.h> |
86 | #include <linux/kdebug.h> | 86 | #include <linux/kdebug.h> |
87 | #include <linux/cpu.h> | 87 | #include <linux/cpu.h> |
88 | #include <linux/gfp.h> | ||
88 | 89 | ||
89 | #include <asm/delay.h> | 90 | #include <asm/delay.h> |
90 | #include <asm/machvec.h> | 91 | #include <asm/machvec.h> |
@@ -888,9 +889,10 @@ ia64_mca_modify_comm(const struct task_struct *previous_current) | |||
888 | } | 889 | } |
889 | 890 | ||
890 | static void | 891 | static void |
891 | finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, | 892 | finish_pt_regs(struct pt_regs *regs, struct ia64_sal_os_state *sos, |
892 | unsigned long *nat) | 893 | unsigned long *nat) |
893 | { | 894 | { |
895 | const pal_min_state_area_t *ms = sos->pal_min_state; | ||
894 | const u64 *bank; | 896 | const u64 *bank; |
895 | 897 | ||
896 | /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use | 898 | /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use |
@@ -904,6 +906,10 @@ finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, | |||
904 | regs->cr_iip = ms->pmsa_xip; | 906 | regs->cr_iip = ms->pmsa_xip; |
905 | regs->cr_ipsr = ms->pmsa_xpsr; | 907 | regs->cr_ipsr = ms->pmsa_xpsr; |
906 | regs->cr_ifs = ms->pmsa_xfs; | 908 | regs->cr_ifs = ms->pmsa_xfs; |
909 | |||
910 | sos->iip = ms->pmsa_iip; | ||
911 | sos->ipsr = ms->pmsa_ipsr; | ||
912 | sos->ifs = ms->pmsa_ifs; | ||
907 | } | 913 | } |
908 | regs->pr = ms->pmsa_pr; | 914 | regs->pr = ms->pmsa_pr; |
909 | regs->b0 = ms->pmsa_br0; | 915 | regs->b0 = ms->pmsa_br0; |
@@ -1079,7 +1085,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, | |||
1079 | memcpy(old_regs, regs, sizeof(*regs)); | 1085 | memcpy(old_regs, regs, sizeof(*regs)); |
1080 | old_regs->loadrs = loadrs; | 1086 | old_regs->loadrs = loadrs; |
1081 | old_unat = old_regs->ar_unat; | 1087 | old_unat = old_regs->ar_unat; |
1082 | finish_pt_regs(old_regs, ms, &old_unat); | 1088 | finish_pt_regs(old_regs, sos, &old_unat); |
1083 | 1089 | ||
1084 | /* Next stack a struct switch_stack. mca_asm.S built a partial | 1090 | /* Next stack a struct switch_stack. mca_asm.S built a partial |
1085 | * switch_stack, copy it and fill in the blanks using pt_regs and | 1091 | * switch_stack, copy it and fill in the blanks using pt_regs and |
@@ -1150,7 +1156,7 @@ no_mod: | |||
1150 | mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", | 1156 | mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", |
1151 | smp_processor_id(), type, msg); | 1157 | smp_processor_id(), type, msg); |
1152 | old_unat = regs->ar_unat; | 1158 | old_unat = regs->ar_unat; |
1153 | finish_pt_regs(regs, ms, &old_unat); | 1159 | finish_pt_regs(regs, sos, &old_unat); |
1154 | return previous_current; | 1160 | return previous_current; |
1155 | } | 1161 | } |
1156 | 1162 | ||
@@ -1220,9 +1226,12 @@ static void mca_insert_tr(u64 iord) | |||
1220 | unsigned long psr; | 1226 | unsigned long psr; |
1221 | int cpu = smp_processor_id(); | 1227 | int cpu = smp_processor_id(); |
1222 | 1228 | ||
1229 | if (!ia64_idtrs[cpu]) | ||
1230 | return; | ||
1231 | |||
1223 | psr = ia64_clear_ic(); | 1232 | psr = ia64_clear_ic(); |
1224 | for (i = IA64_TR_ALLOC_BASE; i < IA64_TR_ALLOC_MAX; i++) { | 1233 | for (i = IA64_TR_ALLOC_BASE; i < IA64_TR_ALLOC_MAX; i++) { |
1225 | p = &__per_cpu_idtrs[cpu][iord-1][i]; | 1234 | p = ia64_idtrs[cpu] + (iord - 1) * IA64_TR_ALLOC_MAX; |
1226 | if (p->pte & 0x1) { | 1235 | if (p->pte & 0x1) { |
1227 | old_rr = ia64_get_rr(p->ifa); | 1236 | old_rr = ia64_get_rr(p->ifa); |
1228 | if (old_rr != p->rr) { | 1237 | if (old_rr != p->rr) { |