Re: [Crash-utility] crash 4.0-2.8 fails on 2.6.14-rc5 (EM64T)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> 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;
}


[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux