[PATCH 4/5] powerpc: Make the 64-bit kernel as a position-independent executable

Remi Machet rmachet at slac.stanford.edu
Sat Sep 27 10:10:59 EST 2008


Hi Paul,

This patch breaks my build with the following error:

/u1/rmachet/projects/c2k/linux-powerpc-git $ make cuImage.c2k modules ARCH=powerpc V=1
...
  powerpc-linux-gnu-ld -m elf32ppc  -Bstatic  -o .tmp_vmlinux1 -T arch/powerpc/kernel/vmlinux.lds arch/powerpc/kernel/head_32.o arch/powerpc/kernel/fpu.o  init/built-in.o --start-group  usr/built-in.o  arch/powerpc/kernel/built-in.o  arch/powerpc/mm/built-in.o  arch/powerpc/lib/built-in.o  arch/powerpc/sysdev/built-in.o  arch/powerpc/platforms/built-in.o  kernel/built-in.o  mm/built-in.o  fs/built-in.o  ipc/built-in.o  security/built-in.o  crypto/built-in.o  block/built-in.o  lib/lib.a  lib/built-in.o  drivers/built-in.o  sound/built-in.o  firmware/built-in.o  net/built-in.o --end-group
powerpc-linux-gnu-ld: BFD 2.16.1 internal error, aborting at /u1/rmachet/project/crosstool/crosstool-0.43/build/powerpc-linux-gnu/gcc-4.1.1-glibc-2.3.6/binutils-2.16.1/bfd/elflink.c line 6419 in elf_link_output_extsym

powerpc-linux-gnu-ld: Please report this bug.


I isolated the problem to line 202 in arch/powerpc/kernel/vmlinux.lds.S: If I remove that
line then the kernel builds and run fine on my board (a PowerPC 32bits c2k).
For reference the line is:

	.rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
	{
202->		__rela_dyn_start = .;
		*(.rela*)
	}

Any idea of what cause this crash? I strongly suspect this is a binutils 2.16.1 bug 
that was fixed later but since it may affect other people I just wanted to let you and 
the list know.

Remi


On Sat, 2008-08-30 at 11:43 +1000, Paul Mackerras wrote:
> This implements CONFIG_RELOCATABLE for 64-bit by making the kernel as
> a position-independent executable (PIE) when it is set.  This involves
> processing the dynamic relocations in the image in the early stages of
> booting, even if the kernel is being run at the address it is linked at,
> since the linker does not necessarily fill in words in the image for
> which there are dynamic relocations.  (In fact the linker does fill in
> such words for 64-bit executables, though not for 32-bit executables,
> so in principle we could avoid calling relocate() entirely when we're
> running a 64-bit kernel at the linked address.)
> 
> The dynamic relocations are processed by a new function relocate(addr),
> where the addr parameter is the virtual address where the image will be
> run.  In fact we call it twice; once before calling prom_init, and again
> when starting the main kernel.  This means that reloc_offset() returns
> 0 in prom_init (since it has been relocated to the address it is running
> at), which necessitated a few adjustments.
> 
> This also changes __va and __pa to use an equivalent definition that is
> simpler.  With the relocatable kernel, PAGE_OFFSET and MEMORY_START are
> constants (for 64-bit) whereas PHYSICAL_START is a variable (and
> KERNELBASE ideally should be too, but isn't yet).
> 
> With this, relocatable kernels still copy themselves down to physical
> address 0 and run there.
> 
> Signed-off-by: Paul Mackerras <paulus at samba.org>
> ---
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 587da5e..17c988b 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -806,6 +806,19 @@ config PIN_TLB
>  endmenu
>  
>  if PPC64
> +config RELOCATABLE
> +	bool "Build a relocatable kernel"
> +	help
> +	  This builds a kernel image that is capable of running anywhere
> +	  in the RMA (real memory area) at any 16k-aligned base address.
> +	  The kernel is linked as a position-independent executable (PIE)
> +	  and contains dynamic relocations which are processed early
> +	  in the bootup process.
> +
> +	  One use is for the kexec on panic case where the recovery kernel
> +	  must live at a different physical address than the primary
> +	  kernel.
> +
>  config PAGE_OFFSET
>  	hex
>  	default "0xc000000000000000"
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index 9155c93..14c86fe 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -63,7 +63,9 @@ override CC	+= -m$(CONFIG_WORD_SIZE)
>  override AR	:= GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR)
>  endif
>  
> -LDFLAGS_vmlinux	:= -Bstatic
> +LDFLAGS_vmlinux-yy := -Bstatic
> +LDFLAGS_vmlinux-$(CONFIG_PPC64)$(CONFIG_RELOCATABLE) := -pie
> +LDFLAGS_vmlinux	:= $(LDFLAGS_vmlinux-yy)
>  
>  CFLAGS-$(CONFIG_PPC64)	:= -mminimal-toc -mtraceback=none  -mcall-aixdesc
>  CFLAGS-$(CONFIG_PPC32)	:= -ffixed-r2 -mmultiple
> diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
> index 14174aa..9109e1f 100644
> --- a/arch/powerpc/boot/Makefile
> +++ b/arch/powerpc/boot/Makefile
> @@ -310,8 +310,11 @@ $(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb
>  $(obj)/vmlinux.strip: vmlinux
>  	$(STRIP) -s -R .comment $< -o $@
>  
> +# The iseries hypervisor won't take an ET_DYN executable, so this
> +# changes the type (byte 17) in the file to ET_EXEC (2).
>  $(obj)/zImage.iseries: vmlinux
>  	$(STRIP) -s -R .comment $< -o $@
> +	printf "\x02" | dd of=$@ conv=notrunc bs=1 seek=17
>  
>  $(obj)/uImage: vmlinux $(wrapperbits)
>  	$(call if_changed,wrap,uboot)
> diff --git a/arch/powerpc/boot/elf_util.c b/arch/powerpc/boot/elf_util.c
> index 7454aa4..1567a0c 100644
> --- a/arch/powerpc/boot/elf_util.c
> +++ b/arch/powerpc/boot/elf_util.c
> @@ -27,7 +27,8 @@ int parse_elf64(void *hdr, struct elf_info *info)
>  	      elf64->e_ident[EI_MAG3]  == ELFMAG3	&&
>  	      elf64->e_ident[EI_CLASS] == ELFCLASS64	&&
>  	      elf64->e_ident[EI_DATA]  == ELFDATA2MSB	&&
> -	      elf64->e_type            == ET_EXEC	&&
> +	      (elf64->e_type            == ET_EXEC ||
> +	       elf64->e_type            == ET_DYN)	&&
>  	      elf64->e_machine         == EM_PPC64))
>  		return 0;
>  
> @@ -58,7 +59,8 @@ int parse_elf32(void *hdr, struct elf_info *info)
>  	      elf32->e_ident[EI_MAG3]  == ELFMAG3	&&
>  	      elf32->e_ident[EI_CLASS] == ELFCLASS32	&&
>  	      elf32->e_ident[EI_DATA]  == ELFDATA2MSB	&&
> -	      elf32->e_type            == ET_EXEC	&&
> +	      (elf32->e_type            == ET_EXEC ||
> +	       elf32->e_type            == ET_DYN)      &&
>  	      elf32->e_machine         == EM_PPC))
>  		return 0;
>  
> diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
> index c2df53c..5a44174 100644
> --- a/arch/powerpc/include/asm/mmu-hash64.h
> +++ b/arch/powerpc/include/asm/mmu-hash64.h
> @@ -437,7 +437,7 @@ typedef struct {
>  	})
>  #endif /* 1 */
>  
> -/* This is only valid for addresses >= KERNELBASE */
> +/* This is only valid for addresses >= PAGE_OFFSET */
>  static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
>  {
>  	if (ssize == MMU_SEGSIZE_256M)
> diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
> index e088545..64e1445 100644
> --- a/arch/powerpc/include/asm/page.h
> +++ b/arch/powerpc/include/asm/page.h
> @@ -71,15 +71,21 @@
>  #define PAGE_OFFSET	ASM_CONST(CONFIG_PAGE_OFFSET)
>  #define LOAD_OFFSET	ASM_CONST((CONFIG_KERNEL_START-CONFIG_PHYSICAL_START))
>  
> -#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_FLATMEM)
> +#if defined(CONFIG_RELOCATABLE)
>  #ifndef __ASSEMBLY__
>  extern phys_addr_t memstart_addr;
>  extern phys_addr_t kernstart_addr;
>  #endif
>  #define PHYSICAL_START	kernstart_addr
> -#define MEMORY_START	memstart_addr
>  #else
>  #define PHYSICAL_START	ASM_CONST(CONFIG_PHYSICAL_START)
> +#endif
> +
> +#ifdef CONFIG_PPC64
> +#define MEMORY_START	0UL
> +#elif defined(CONFIG_RELOCATABLE)
> +#define MEMORY_START	memstart_addr
> +#else
>  #define MEMORY_START	(PHYSICAL_START + PAGE_OFFSET - KERNELBASE)
>  #endif
>  
> @@ -92,8 +98,8 @@ extern phys_addr_t kernstart_addr;
>  #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
>  #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
>  
> -#define __va(x) ((void *)((unsigned long)(x) - PHYSICAL_START + KERNELBASE))
> -#define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE)
> +#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - MEMORY_START))
> +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START)
>  
>  /*
>   * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
> diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
> index 916018e..14c0f45 100644
> --- a/arch/powerpc/include/asm/sections.h
> +++ b/arch/powerpc/include/asm/sections.h
> @@ -16,6 +16,12 @@ static inline int in_kernel_text(unsigned long addr)
>  	return 0;
>  }
>  
> +static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
> +{
> +	return start < (unsigned long)__init_end &&
> +		(unsigned long)_stext < end;
> +}
> +
>  #endif
>  
>  #endif /* __KERNEL__ */
> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
> index 64f5948..1fbc953 100644
> --- a/arch/powerpc/kernel/Makefile
> +++ b/arch/powerpc/kernel/Makefile
> @@ -34,6 +34,7 @@ obj-$(CONFIG_PPC64)		+= setup_64.o sys_ppc32.o \
>  				   paca.o cpu_setup_ppc970.o \
>  				   cpu_setup_pa6t.o \
>  				   firmware.o nvram_64.o
> +obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
>  obj-$(CONFIG_PPC64)		+= vdso64/
>  obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
>  obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
> diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
> index df678ee..c0bba84 100644
> --- a/arch/powerpc/kernel/head_64.S
> +++ b/arch/powerpc/kernel/head_64.S
> @@ -1360,6 +1360,12 @@ _INIT_STATIC(__boot_from_prom)
>  	 */
>  	rldicr	r1,r1,0,59
>  
> +#ifdef CONFIG_RELOCATABLE
> +	/* Relocate code for where we are now */
> +	mr	r3,r26
> +	bl	.relocate
> +#endif
> +
>  	/* Restore parameters */
>  	mr	r3,r31
>  	mr	r4,r30
> @@ -1368,11 +1374,19 @@ _INIT_STATIC(__boot_from_prom)
>  	mr	r7,r27
>  
>  	/* Do all of the interaction with OF client interface */
> +	mr	r8,r26
>  	bl	.prom_init
>  	/* We never return */
>  	trap
>  
>  _STATIC(__after_prom_start)
> +#ifdef CONFIG_RELOCATABLE
> +	/* process relocations for the final address of the kernel */
> +	lis	r25,PAGE_OFFSET at highest	/* compute virtual base of kernel */
> +	sldi	r25,r25,32
> +	mr	r3,r25
> +	bl	.relocate
> +#endif
>  
>  /*
>   * We need to run with _stext at physical address PHYSICAL_START.
> @@ -1381,10 +1395,9 @@ _STATIC(__after_prom_start)
>   *
>   * Note: This process overwrites the OF exception vectors.
>   */
> -	LOAD_REG_IMMEDIATE(r3, PHYSICAL_START)	/* target addr */
> -	cmpd	r3,r26			/* In some cases the loader may  */
> +	li	r3,0			/* target addr */
> +	mr.	r4,r26			/* In some cases the loader may  */
>  	beq	9f			/* have already put us at zero */
> -	mr	r4,r26			/* source address */
>  	lis	r5,(copy_to_here - _stext)@ha
>  	addi	r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
>  	li	r6,0x100		/* Start offset, the first 0x100 */
> @@ -1617,6 +1630,13 @@ _INIT_STATIC(start_here_multiplatform)
>  	ori	r6,r6,MSR_RI
>  	mtmsrd	r6			/* RI on */
>  
> +#ifdef CONFIG_RELOCATABLE
> +	/* Save the physical address we're running at in kernstart_addr */
> +	LOAD_REG_ADDR(r4, kernstart_addr)
> +	clrldi	r0,r25,2
> +	std	r0,0(r4)
> +#endif
> +
>  	/* The following gets the stack set up with the regs */
>  	/* pointing to the real addr of the kernel stack.  This is   */
>  	/* all done to support the C function call below which sets  */
> diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
> index 623e8c3..48a3471 100644
> --- a/arch/powerpc/kernel/paca.c
> +++ b/arch/powerpc/kernel/paca.c
> @@ -12,6 +12,7 @@
>  
>  #include <asm/lppaca.h>
>  #include <asm/paca.h>
> +#include <asm/sections.h>
>  
>  /* This symbol is provided by the linker - let it fill in the paca
>   * field correctly */
> @@ -79,7 +80,7 @@ void __init initialise_pacas(void)
>  		new_paca->lock_token = 0x8000;
>  		new_paca->paca_index = cpu;
>  		new_paca->kernel_toc = kernel_toc;
> -		new_paca->kernelbase = KERNELBASE;
> +		new_paca->kernelbase = (unsigned long) _stext;
>  		new_paca->kernel_msr = MSR_KERNEL;
>  		new_paca->hw_cpu_id = 0xffff;
>  		new_paca->slb_shadow_ptr = &slb_shadow[cpu];
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 87d83c5..3b93ed4 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -1164,6 +1164,9 @@ void __init early_init_devtree(void *params)
>  
>  	/* Reserve LMB regions used by kernel, initrd, dt, etc... */
>  	lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
> +	/* If relocatable, reserve first 32k for interrupt vectors etc. */
> +	if (PHYSICAL_START > MEMORY_START)
> +		lmb_reserve(MEMORY_START, 0x8000);
>  	reserve_kdump_trampoline();
>  	reserve_crashkernel();
>  	early_reserve_mem();
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 1f89885..7cf274a 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -2309,13 +2309,14 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
>  
>  unsigned long __init prom_init(unsigned long r3, unsigned long r4,
>  			       unsigned long pp,
> -			       unsigned long r6, unsigned long r7)
> +			       unsigned long r6, unsigned long r7,
> +			       unsigned long kbase)
>  {	
>  	struct prom_t *_prom;
>  	unsigned long hdr;
> -	unsigned long offset = reloc_offset();
>  
>  #ifdef CONFIG_PPC32
> +	unsigned long offset = reloc_offset();
>  	reloc_got2(offset);
>  #endif
>  
> @@ -2349,9 +2350,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
>  	 */
>  	RELOC(of_platform) = prom_find_machine_type();
>  
> +#ifndef CONFIG_RELOCATABLE
>  	/* Bail if this is a kdump kernel. */
>  	if (PHYSICAL_START > 0)
>  		prom_panic("Error: You can't boot a kdump kernel from OF!\n");
> +#endif
>  
>  	/*
>  	 * Check for an initrd
> @@ -2371,7 +2374,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
>  	 * Copy the CPU hold code
>  	 */
>  	if (RELOC(of_platform) != PLATFORM_POWERMAC)
> -		copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
> +		copy_and_flush(0, kbase, 0x100, 0);
>  
>  	/*
>  	 * Do early parsing of command line
> @@ -2474,7 +2477,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
>  	reloc_got2(-offset);
>  #endif
>  
> -	__start(hdr, KERNELBASE + offset, 0);
> +	__start(hdr, kbase, 0);
>  
>  	return 0;
>  }
> diff --git a/arch/powerpc/kernel/reloc_64.S b/arch/powerpc/kernel/reloc_64.S
> new file mode 100644
> index 0000000..b47a0e1
> --- /dev/null
> +++ b/arch/powerpc/kernel/reloc_64.S
> @@ -0,0 +1,87 @@
> +/*
> + * Code to process dynamic relocations in the kernel.
> + *
> + * Copyright 2008 Paul Mackerras, IBM Corp.
> + *
> + *  This program is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU General Public License
> + *  as published by the Free Software Foundation; either version
> + *  2 of the License, or (at your option) any later version.
> + */
> +
> +#include <asm/ppc_asm.h>
> +
> +RELA = 7
> +RELACOUNT = 0x6ffffff9
> +R_PPC64_RELATIVE = 22
> +
> +/*
> + * r3 = desired final address of kernel
> + */
> +_GLOBAL(relocate)
> +	mflr	r0
> +	bcl	20,31,$+4
> +0:	mflr	r12		/* r12 has runtime addr of label 0 */
> +	mtlr	r0
> +	ld	r11,(p_dyn - 0b)(r12)
> +	add	r11,r11,r12	/* r11 has runtime addr of .dynamic section */
> +	ld	r9,(p_rela - 0b)(r12)
> +	add	r9,r9,r12	/* r9 has runtime addr of .rela.dyn section */
> +	ld	r10,(p_st - 0b)(r12)
> +	add	r10,r10,r12	/* r10 has runtime addr of _stext */
> +
> +	/*
> +	 * Scan the dynamic section for the RELA and RELACOUNT entries.
> +	 */
> +	li	r7,0
> +	li	r8,0
> +1:	ld	r6,0(r11)	/* get tag */
> +	cmpdi	r6,0
> +	beq	4f		/* end of list */
> +	cmpdi	r6,RELA
> +	bne	2f
> +	ld	r7,8(r11)	/* get RELA pointer in r7 */
> +	b	3f
> +2:	addis	r6,r6,(-RELACOUNT)@ha
> +	cmpdi	r6,RELACOUNT at l
> +	bne	3f
> +	ld	r8,8(r11)	/* get RELACOUNT value in r8 */
> +3:	addi	r11,r11,16
> +	b	1b
> +4:	cmpdi	r7,0		/* check we have both RELA and RELACOUNT */
> +	cmpdi	cr1,r8,0
> +	beq	6f
> +	beq	cr1,6f
> +
> +	/*
> +	 * Work out linktime address of _stext and hence the
> +	 * relocation offset to be applied.
> +	 * cur_offset [r7] = rela.run [r9] - rela.link [r7]
> +	 * _stext.link [r10] = _stext.run [r10] - cur_offset [r7]
> +	 * final_offset [r3] = _stext.final [r3] - _stext.link [r10]
> +	 */
> +	subf	r7,r7,r9	/* cur_offset */
> +	subf	r10,r7,r10
> +	subf	r3,r10,r3	/* final_offset */
> +
> +	/*
> +	 * Run through the list of relocations and process the
> +	 * R_PPC64_RELATIVE ones.
> +	 */
> +	mtctr	r8
> +5:	lwz	r0,12(9)	/* ELF64_R_TYPE(reloc->r_info) */
> +	cmpwi	r0,R_PPC64_RELATIVE
> +	bne	6f
> +	ld	r6,0(r9)	/* reloc->r_offset */
> +	ld	r0,16(r9)	/* reloc->r_addend */
> +	add	r0,r0,r3
> +	stdx	r0,r7,r6
> +	addi	r9,r9,24
> +	bdnz	5b
> +
> +6:	blr
> +
> +p_dyn:	.llong	__dynamic_start - 0b
> +p_rela:	.llong	__rela_dyn_start - 0b
> +p_st:	.llong	_stext - 0b
> +
> diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
> index 4a8ce62..4994aa0 100644
> --- a/arch/powerpc/kernel/vmlinux.lds.S
> +++ b/arch/powerpc/kernel/vmlinux.lds.S
> @@ -186,6 +186,21 @@ SECTIONS
>  		*(.machine.desc)
>  		__machine_desc_end = . ;
>  	}
> +	. = ALIGN(8);
> +	.dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET) { *(.dynsym) }
> +	.dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) }
> +	.dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET)
> +	{
> +		__dynamic_start = .;
> +		*(.dynamic)
> +	}
> +	.hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
> +	.interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
> +	.rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
> +	{
> +		__rela_dyn_start = .;
> +		*(.rela*)
> +	}
>  
>  	/* freed after init ends here */
>  	. = ALIGN(PAGE_SIZE);
> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
> index 1fe7ac6..97b16d5 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -194,7 +194,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
>  		unsigned long tprot = prot;
>  
>  		/* Make kernel text executable */
> -		if (in_kernel_text(vaddr))
> +		if (overlaps_kernel_text(vaddr, vaddr + step))
>  			tprot &= ~HPTE_R_N;
>  
>  		hash = hpt_hash(va, shift, ssize);
> diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
> index 4ae3d00..40f72c2 100644
> --- a/arch/powerpc/platforms/powermac/smp.c
> +++ b/arch/powerpc/platforms/powermac/smp.c
> @@ -787,7 +787,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
>  {
>  	unsigned int save_vector;
>  	unsigned long target, flags;
> -	unsigned int *vector = (unsigned int *)(KERNELBASE+0x100);
> +	unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
>  
>  	if (nr < 0 || nr > 3)
>  		return;
> @@ -801,7 +801,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
>  	save_vector = *vector;
>  
>  	/* Setup fake reset vector that does
> -	 *   b __secondary_start_pmac_0 + nr*8 - KERNELBASE
> +	 *   b __secondary_start_pmac_0 + nr*8
>  	 */
>  	target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
>  	patch_branch(vector, target, BRANCH_SET_LINK);
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev




More information about the Linuxppc-dev mailing list