Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1503

kernel-2.6.18-238.el5.src.rpm

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;