Current code is setting {hard,soft}irq_ctx[] to (irq_ctx **), because per_cpu symbol itself is pointer of specified type (irq_ctx *). But, I wonder how this works in past, the code is expecting {hard,soft}_ctx[] are (irq_ctx *). This fixes by deref per_cpu in initialization, and set expected pointers. Tested on i386 v3.10. --- task.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff -puN task.c~ia32-irq-stack-fix task.c --- crash-64/task.c~ia32-irq-stack-fix 2017-02-08 17:37:33.126367767 +0900 +++ crash-64-hirofumi/task.c 2017-02-08 17:46:06.900703326 +0900 @@ -570,10 +570,20 @@ irqstacks_init(void) if ((hard_sp = per_cpu_symbol_search("per_cpu__hardirq_ctx"))) { if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) { for (i = 0; i < NR_CPUS; i++) { + ulong ptr; + if (!kt->__per_cpu_offset[i]) continue; - tt->hardirq_ctx[i] = hard_sp->value + - kt->__per_cpu_offset[i]; + ptr = hard_sp->value + kt->__per_cpu_offset[i]; + + if (!readmem(ptr, KVADDR, &ptr, + sizeof(void *), "hardirq ctx", + RETURN_ON_ERROR)) { + error(INFO, "cannot read hardirq_ctx[%d] at %lx\n", + i, ptr); + continue; + } + tt->hardirq_ctx[i] = ptr; } } else tt->hardirq_ctx[0] = hard_sp->value; @@ -604,10 +614,20 @@ irqstacks_init(void) if ((soft_sp = per_cpu_symbol_search("per_cpu__softirq_ctx"))) { if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) { for (i = 0; i < NR_CPUS; i++) { + ulong ptr; + if (!kt->__per_cpu_offset[i]) continue; - tt->softirq_ctx[i] = soft_sp->value + - kt->__per_cpu_offset[i]; + ptr = soft_sp->value + kt->__per_cpu_offset[i]; + + if (!readmem(ptr, KVADDR, &ptr, + sizeof(void *), "softirq ctx", + RETURN_ON_ERROR)) { + error(INFO, "cannot read softirq_ctx[%d] at %lx\n", + i, ptr); + continue; + } + tt->softirq_ctx[i] = ptr; } } else tt->softirq_ctx[0] = soft_sp->value; -- OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx> -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility