[Cbe-oss-dev] [PATCH] fix reboot fail on kexec for CBE

Arnd Bergmann arnd at arndb.de
Wed Apr 4 00:12:08 EST 2007


On Tuesday 03 April 2007, Akira Tsukamoto wrote:
> [PATCH] fix reboot fail on kexec for CBE
> 
> This patch adds additional TLB flush for dump-capture kernel to 
> successfully reboot triggered by kexec. 
> 
> The same issue might exist on PS3 platform but I have not tried 
> yet and the patch only applies to CBE platform.
> I really appreciate if somebody could brush up this patch, as such 
> using magic constant value inside the code.

Thanks for the Information! Is this patch actually sufficient in that
it enables kexec to work as expected, or did you need additional changes
beyond it?

> ---------------------------------------------------------------
> diff -uprNX dontdiff linux-2.6.20.4-arnd3/arch/powerpc/kernel/head_64.S linux-2.6.20.4-arnd3-aki1/arch/powerpc/kernel/head_64.S
> --- linux-2.6.20.4-arnd3/arch/powerpc/kernel/head_64.S	2007-03-30 17:13:53.000000000 +0900
> +++ linux-2.6.20.4-arnd3-aki1/arch/powerpc/kernel/head_64.S	2007-03-30 18:54:51.000000000 +0900
> @@ -2010,6 +2010,9 @@ _STATIC(start_here_multiplatform)
>  	mr	r3,r31
>   	bl	.early_setup
>  
> +#if defined(CONFIG_PPC_CELL) && defined(CONFIG_CRASH_DUMP)
> +	bl	.cbe_flush_tlb
> +#endif
>  	LOAD_REG_IMMEDIATE(r3, .start_here_common)
>  	LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
>  	mtspr	SPRN_SRR0,r3

This looks wrong, the function is called on all platforms, if
support for cell is compiled in. Since CONFIG_PPC_CELL is set on
the PS3, it is even active there.

> diff -uprNX dontdiff linux-2.6.20.4-arnd3/arch/powerpc/platforms/cell/cbe_regs.c linux-2.6.20.4-arnd3-aki1/arch/powerpc/platforms/cell/cbe_regs.c
> --- linux-2.6.20.4-arnd3/arch/powerpc/platforms/cell/cbe_regs.c	2007-03-30 17:25:29.000000000 +0900
> +++ linux-2.6.20.4-arnd3-aki1/arch/powerpc/platforms/cell/cbe_regs.c	2007-03-30 18:51:22.000000000 +0900
> @@ -273,3 +273,21 @@ void __init cbe_regs_init(void)
>  	}
>  }
>  
> +asmlinkage void cbe_flush_tlb(void)
> +{
> +	int i,j;
> +	unsigned long tmp;
> +	int ti,ts;
> +
> +	for (i = 0; i < 256; i++) {
> +		ti = 0x10 * i;
> +		for (j = 0; j < 4; j++) {
> +			ts = 1 << j;
> +			tmp = ti | ts;
> +			mtspr(947, tmp);
> +			mtspr(948, 0);
> +		}
> +	}
> +
> +}
> +

But the SPRs you are touching are CPU specific. Writing into them when a
hypervisor is enabled or when running on a different CPU altogether
probably leads to a nasty exception.

I think it should instead be done from the ->cpu_setup function in
identify_cpu(). Can you try if that works?

A better alternative might be to flush the TLBs from the old kernel
before calling into the new one, at least that's how I'd expect kexec
to work.

	Arnd <><



More information about the cbe-oss-dev mailing list