--- crash-4.0-2.21/ppc64.c.orig 2006-03-08 10:59:13.000000000 -0800 +++ crash-4.0-2.21/ppc64.c 2006-03-05 13:49:52.000000000 -0800 @@ -1184,8 +1184,12 @@ ppc64_back_trace(struct gnu_request *req ms->hwstacksize + STACK_FRAME_OVERHEAD; bt->stackbuf = ms->hwstackbuf; alter_stackbuf(bt); - } else - error(FATAL, "cannot find the stack info"); + } else { + if (CRASHDEBUG(1)) { + fprintf(fp, "cannot find the stack info.\n"); + } + return; + } } @@ -1493,9 +1497,19 @@ ppc64_kdump_stack_frame(struct bt_info * return FALSE; } *ksp = pt_regs->gpr[1]; - readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value", - FAULT_ON_ERROR); - *nip = unip; + if (IS_KVADDR(*ksp)) { + readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value", + FAULT_ON_ERROR); + *nip = unip; + } else { + if (IN_TASK_VMA(bt_in->task, *ksp)) + fprintf(fp, "%0lx: Task is running in user space\n", + bt_in->task); + else + fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n", + bt_in->task, *ksp); + *nip = pt_regs->nip; + } if (bt_in->flags && ((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT))) @@ -1505,7 +1519,9 @@ ppc64_kdump_stack_frame(struct bt_info * * Print the collected regs for the active task */ ppc64_print_regs(pt_regs); - + if (!IS_KVADDR(*ksp)) + return FALSE; + fprintf(fp, " NIP [%016lx] %s\n", pt_regs->nip, closest_symbol(pt_regs->nip)); if (unip != pt_regs->link) @@ -1538,7 +1554,7 @@ ppc64_get_dumpfile_stack_frame(struct bt /* * For the kdump vmcore, Use SP and IP values that are saved in ptregs. */ - if (pc->flags && KDUMP) + if (pc->flags & KDUMP) return ppc64_kdump_stack_frame(bt_in, nip, ksp); bt = &bt_local; @@ -2282,21 +2298,22 @@ parse_cmdline_arg(void) static void ppc64_paca_init(void) { +#define BITS_FOR_LONG sizeof(ulong)*8 int i, cpus, nr_paca; char *cpu_paca_buf; ulong data_offset; - ulong per_cpu_offset; - ulong cpuid_offset; - signed short cpuid; + ulong cpu_online_map[NR_CPUS/BITS_FOR_LONG]; - if (!symbol_exists("paca")) + if (!symbol_exists("paca") || !symbol_exists("cpu_online_map")) return; if (!MEMBER_EXISTS("paca_struct", "data_offset")) return; + readmem(symbol_value("cpu_online_map"), KVADDR, &cpu_online_map[0], + NR_CPUS/8, "cpu_online_map", FAULT_ON_ERROR); + STRUCT_SIZE_INIT(ppc64_paca, "paca_struct"); - cpuid_offset = MEMBER_OFFSET("paca_struct", "hw_cpu_id"); data_offset = MEMBER_OFFSET("paca_struct", "data_offset"); cpu_paca_buf = GETBUF(SIZE(ppc64_paca)); @@ -2305,16 +2322,18 @@ ppc64_paca_init(void) nr_paca = NR_CPUS; for (i = cpus = 0; i < nr_paca; i++) { + div_t val = div(i, BITS_FOR_LONG); + /* + * CPU online? + */ + if (!(cpu_online_map[val.quot] & (0x1UL << val.rem))) + continue; + readmem(symbol_value("paca") + (i * SIZE(ppc64_paca)), KVADDR, cpu_paca_buf, SIZE(ppc64_paca), "paca entry", FAULT_ON_ERROR); - cpuid = SHORT(cpu_paca_buf + cpuid_offset); - if (cpuid == -1) - continue; - - per_cpu_offset = ULONG(cpu_paca_buf + data_offset); - kt->__per_cpu_offset[i] = per_cpu_offset; + kt->__per_cpu_offset[i] = ULONG(cpu_paca_buf + data_offset); kt->flags |= PER_CPU_OFF; cpus++; }