> Can you show your new versions of x86_64_cpu_pda_init() and > x86_64_get_smp_cpus()?
/* * Gather the cpu_pda array info, updating any smp-related items that * were possibly bypassed or improperly initialized in kernel_init(). */ static void x86_64_cpu_pda_init(void) { int i, cpus, nr_pda, cpunumber; char *cpu_pda_buf; ulong level4_pgt, data_offset; struct syment *sp, *nsp; ulong offset, istacksize; STRUCT_SIZE_INIT(x8664_pda, "x8664_pda"); MEMBER_OFFSET_INIT(x8664_pda_pcurrent, "x8664_pda", "pcurrent"); MEMBER_OFFSET_INIT(x8664_pda_data_offset, "x8664_pda", "data_offset"); MEMBER_OFFSET_INIT(x8664_pda_kernelstack, "x8664_pda", "kernelstack"); MEMBER_OFFSET_INIT(x8664_pda_irqrsp, "x8664_pda", "irqrsp"); MEMBER_OFFSET_INIT(x8664_pda_irqstackptr, "x8664_pda", "irqstackptr"); MEMBER_OFFSET_INIT(x8664_pda_level4_pgt, "x8664_pda", "level4_pgt"); MEMBER_OFFSET_INIT(x8664_pda_cpunumber, "x8664_pda", "cpunumber"); MEMBER_OFFSET_INIT(x8664_pda_me, "x8664_pda", "me"); cpu_pda_buf = GETBUF(SIZE(x8664_pda)); if (!(nr_pda = get_array_length("cpu_pda", NULL, 0))) nr_pda = NR_CPUS; for (i = cpus = 0; i < nr_pda; i++) { if (!CPU_PDA_READ(i, cpu_pda_buf)) break; if (VALID_MEMBER(x8664_pda_level4_pgt)) { level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt)); if (!VALID_LEVEL4_PGT_ADDR(level4_pgt)) break; } cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber)); if (cpunumber != cpus) break; cpus++; if (VALID_MEMBER(x8664_pda_data_offset)) { data_offset = ULONG(cpu_pda_buf + OFFSET(x8664_pda_data_offset)); kt->__per_cpu_offset[i] = data_offset; kt->flags |= PER_CPU_OFF; } else data_offset = 0; machdep->machspec->stkinfo.ibase[i] = ULONG(cpu_pda_buf + OFFSET(x8664_pda_irqstackptr)); if (CRASHDEBUG(2)) fprintf(fp, "CPU%d: level4_pgt: %lx data_offset: %lx\n", i, level4_pgt, data_offset); } if ((i = get_array_length("boot_cpu_stack", NULL, 0))) { istacksize = i; } else if ((sp = symbol_search("boot_cpu_stack")) && (nsp = next_symbol(NULL, sp))) { istacksize = (nsp->value - sp->value) & ~(PAGESIZE()-1); if (istacksize != 16384) error(WARNING, "calculated irqstack size of %ld != 16K?\n\n", istacksize); } else istacksize = 16384; machdep->machspec->stkinfo.isize = istacksize; /* * Adjust the kernel top-of-stack values down to their base. */ for (i = 0; i < NR_CPUS; i++) { if (machdep->machspec->stkinfo.ibase[i]) machdep->machspec->stkinfo.ibase[i] -= (istacksize-64); else break; } /* * Sanity check cpu 0's IRQ stack, which should be located at * the address of &boot_cpu_stack[0]. */ sp = value_search(machdep->machspec->stkinfo.ibase[0], &offset); if (!sp || offset || !STREQ(sp->name, "boot_cpu_stack")) { if (symbol_value("boot_cpu_stack")) { error(WARNING, "cpu 0 IRQ stack: %lx\n boot_cpu_stack: %lx\n\n", machdep->machspec->stkinfo.ibase[0], symbol_value("boot_cpu_stack")); if (!machdep->machspec->stkinfo.ibase[0]) machdep->machspec->stkinfo.ibase[0] = symbol_value("boot_cpu_stack"); } else error(WARNING, "boot_cpu_stack: symbol does not exist in this kernel!\n"); } kt->cpus = cpus; if (kt->cpus > 1) kt->flags |= SMP; verify_spinlock(); FREEBUF(cpu_pda_buf); } /* * Override smp_num_cpus if possible and necessary. */ int x86_64_get_smp_cpus(void) { int i, cpus, nr_pda, cpunumber; char *cpu_pda_buf; ulong level4_pgt; if (!VALID_STRUCT(x8664_pda)) return 1; cpu_pda_buf = GETBUF(SIZE(x8664_pda)); if (!(nr_pda = get_array_length("cpu_pda", NULL, 0))) nr_pda = NR_CPUS; for (i = cpus = 0; i < nr_pda; i++) { if (!CPU_PDA_READ(i, cpu_pda_buf)) break; if (VALID_MEMBER(x8664_pda_level4_pgt)) { level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt)); if (!VALID_LEVEL4_PGT_ADDR(level4_pgt)) break; } cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber)); if (cpunumber != cpus) break; cpus++; } FREEBUF(cpu_pda_buf); return cpus; }