From: Takao Indoh <tindoh@redhat.com> Date: Thu, 2 Sep 2010 17:23:22 -0400 Subject: [ia64] mca: save I-resources when INIT is sent Message-id: <20100902172322.21230.41142.sendpatchset@flat.lab.bos.redhat.com> Patchwork-id: 28022 O-Subject: [RHEL5.6 PATCH][kdump] ia64: Save I-resources when INIT is sent Bugzilla: 471136 RH-Acked-by: Dave Anderson <anderson@redhat.com> RH-Acked-by: Prarit Bhargava <prarit@redhat.com> BZ#471136 https://bugzilla.redhat.com/show_bug.cgi?id=471136 This is a backport of 9ee27c76393394c7fb1ddeca3f1622d4537185a0. [Summary] When INIT is sent, ip/psr/pfs register is stored in the iip/ipsr/ifs register, and then they are copied to the pmsa_{iip,ipsr,ifs}. But when pt_regs is created, pmsa_{iip,ipsr,ifs} is not used if PSR.ic is 0. finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, unsigned long *nat) { (snip) if (ia64_psr(regs)->ic) { regs->cr_iip = ms->pmsa_iip; regs->cr_ipsr = ms->pmsa_ipsr; regs->cr_ifs = ms->pmsa_ifs; } else { regs->cr_iip = ms->pmsa_xip; regs->cr_ipsr = ms->pmsa_xpsr; regs->cr_ifs = ms->pmsa_xfs; } Therefore, when you investigate crash dump, iip register in pt_regs does not point to the context which was interrupted by INIT. [How to fix] In upstream kernel, new members were added into struct ia64_sal_os_state and iip/ipsr/ifs register are stored there when PSR.ic is 0, so that user can know them when debugging. At first I tried to do the same thing against rhel kernel, but it seems to break kabi. So I added new static variables where iip/ipsr/ifs register are saved. Please let me know if there is another idea. [Upstream] Included in upstream commit 9ee27c76393394c7fb1ddeca3f1622d4537185a0 Author: Takao Indoh <indou.takao@jp.fujitsu.com> Date: Thu Nov 19 16:39:22 2009 -0500 [Test status] I tested on ia64 machine and confirmed iip/ipsr/ifs register are saved correctly. Successful brew scratch build against each arch: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=2720569 Signed-off-by: Jarod Wilson <jarod@redhat.com> diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 88a06d3..86d1390 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -864,11 +864,19 @@ ia64_mca_modify_comm(const struct task_struct *previous_current) memcpy(current->comm, comm, sizeof(current->comm)); } +struct i_resources { + unsigned long iip; + unsigned long ipsr; + unsigned long ifs; +}; +static DEFINE_PER_CPU(struct i_resources, i_resources) = { 0 }; + static void finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, unsigned long *nat) { const u64 *bank; + struct i_resources *res; /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use * pmsa_{xip,xpsr,xfs} @@ -881,6 +889,11 @@ finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, regs->cr_iip = ms->pmsa_xip; regs->cr_ipsr = ms->pmsa_xpsr; regs->cr_ifs = ms->pmsa_xfs; + + res = &get_cpu_var(i_resources); + res->iip = ms->pmsa_iip; + res->ipsr = ms->pmsa_ipsr; + res->ifs = ms->pmsa_ifs; } regs->pr = ms->pmsa_pr; regs->b0 = ms->pmsa_br0;