[PATCH 2/2] powerpc/fsl_booke: enable the relocatable for the kdump kernel

Scott Wood scottwood at freescale.com
Fri Jun 28 12:19:06 EST 2013


On 06/26/2013 09:00:34 PM, Kevin Hao wrote:
> diff --git a/arch/powerpc/include/asm/mmu-book3e.h  
> b/arch/powerpc/include/asm/mmu-book3e.h
> index 936db36..bf422db 100644
> --- a/arch/powerpc/include/asm/mmu-book3e.h
> +++ b/arch/powerpc/include/asm/mmu-book3e.h
> @@ -214,6 +214,11 @@
>  #define TLBILX_T_CLASS2			6
>  #define TLBILX_T_CLASS3			7
> 
> +#ifdef CONFIG_PPC32
> +/* The max size that one tlb can map in a 32bit kernel. */
> +#define PPC_PIN_SIZE	(1 << 28)	/* 256M */
> +#endif

That comment is not true for all chips.

> @@ -177,11 +178,34 @@ unsigned long map_mem_in_cams(unsigned long  
> ram, int max_cam_idx)
>  	unsigned long virt = PAGE_OFFSET;
>  	phys_addr_t phys = memstart_addr;
>  	unsigned long amount_mapped = 0;
> -
> +	unsigned long cam_sz;
> +
> +#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC32)
> +	/*
> +	 * For a relocatable kernel, we would not map from  
> memstart_addr.
> +	 * We first align to PPC_PIN_SIZE (256M), then map the  
> PAGE_OFFSET
> +	 * from there.
> +	 */
> +	phys &= ~(PPC_PIN_SIZE - 1);
> +	ram += memstart_addr & (PPC_PIN_SIZE - 1);

You should not map anything before memstart_addr.  If memstart_addr  
isn't 256M-aligned, you'll have to either use smaller pages or consider  
that region to be "high"mem (assuming Linux supports highmem existing  
below lowmem -- I'm skeptical).

> +	/*
> +	 * For a kdump kernel, we may use a memory area reserved by the  
> boot
> +	 * kernel by using a kernel option like this  
> 'crashkernel=32M at 64M'.
> +	 * In this case, the ram is 96M. The kernel will try to map the  
> first
> +	 * 64M in the first tlb entry. The kernel will definitely get  
> stuck,
> +	 * since the kernel is running above the 64M. So we have to  
> make sure
> +	 * that the first tlb cover the current kernel running address  
> at least.
> +	 */

Maybe we should be running from AS1 when we set this up, to avoid  
problems replacing an entry while it's in use?

Pardon my ignorance about how kdump/kexec works, but I'm a bit confused  
by exactly what the situation is with crashkernel.  How do we know that  
we are the crash kernel, and that we should limit our RAM usage to that  
area?  I'm wondering if this code is assuming that the crashkernel area  
is from where the kernel starts to the end of RAM.

> +	while (1) {
> +		cam_sz = calc_cam_sz(ram, virt, phys);
> +		if (cam_sz + phys > PHYSICAL_START + _end - _stext)
> +			break;
> +		ram = 1 << (ilog2(ram) + 1);
> +	}

The ram that was passed in is as much as you have.  Don't map more.

What happens if (e.g.) memstart_addr is 512M, with a size of 512M, and  
the kernel starts at 768M?  Increasing the size will never get you a  
mapping that covers kernstart, because calc_cam_sz will never return  
more than 256M.

When does memory below the rounded-down kernel start get mapped?

-Scott


More information about the Linuxppc-dev mailing list