From: Mohan Kumar M <mohan@in.ibm.com>
To: Milton Miller <miltonm@bga.com>
Cc: paulus@samba.org, naren@linux.vnet.ibm.com,
ppcdev <linuxppc-dev@ozlabs.org>
Subject: Re: [RFC v3 PATCH 4/4] Relocation support
Date: Tue, 22 Jul 2008 00:53:36 +0530 [thread overview]
Message-ID: <4884E238.8000504@in.ibm.com> (raw)
In-Reply-To: <d8d07a180aaf59d25936ad03c7287f5a@bga.com>
[-- Attachment #1: Type: text/plain, Size: 179 bytes --]
I split the patch 4: Relocation support into 3 patches
1. Generic kernel support for relocatable
2. Kdump kernel support for relocatable
3. LOAD_REG_IMMEDIATE macro replacement
[-- Attachment #2: 0004-Relocation-support.patch --]
[-- Type: text/x-patch, Size: 9689 bytes --]
Relocation support
Add relocatable kernel support like take care when accessing absolute
symbols in the code by adding the relocation kernel base address.
Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
---
arch/powerpc/kernel/head_64.S | 53 ++++++++++++++++++++++++++++++-
arch/powerpc/kernel/machine_kexec_64.c | 4 +-
arch/powerpc/kernel/prom_init.c | 27 ++++++++++++++--
arch/powerpc/kernel/prom_init_check.sh | 2 +-
arch/powerpc/kernel/setup_64.c | 5 +--
arch/powerpc/mm/init_64.c | 7 ++--
arch/powerpc/mm/mem.c | 3 +-
include/asm-powerpc/prom.h | 2 +
include/asm-powerpc/sections.h | 4 ++-
include/asm-powerpc/system.h | 5 +++
10 files changed, 95 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index ecced1e..8adf3b5 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -102,6 +102,12 @@ __secondary_hold_acknowledge:
.llong hvReleaseData-KERNELBASE
#endif /* CONFIG_PPC_ISERIES */
+#ifdef CONFIG_RELOCATABLE_PPC64
+ /* Used as static variable to initialize the reloc_delta */
+__initialized:
+ .long 0x0
+#endif
+
. = 0x60
/*
* The following code is used to hold secondary processors
@@ -1247,6 +1253,38 @@ _STATIC(__mmu_off)
*
*/
_GLOBAL(__start_initialization_multiplatform)
+#ifdef CONFIG_RELOCATABLE_PPC64
+ mr r21,r3
+ mr r22,r4
+ mr r23,r5
+ bl .reloc_offset
+ mr r26,r3
+ mr r3,r21
+ mr r4,r22
+ mr r5,r23
+
+ LOAD_REG_IMMEDIATE(r27, __initialized)
+ add r27,r26,r27
+ ld r7,0(r27)
+ cmpdi r7,0
+ bne 4f
+
+ li r7,1
+ stw r7,0(r27)
+
+ cmpdi r6,0
+ beq 4f
+ LOAD_REG_IMMEDIATE(r27, reloc_delta)
+ add r27,r27,r26
+ std r6,0(r27)
+
+ LOAD_REG_IMMEDIATE(r27, KERNELBASE)
+ add r7,r6,r27
+ LOAD_REG_IMMEDIATE(r27, kernel_base)
+ add r27,r27,r26
+ std r7,0(r27)
+4:
+#endif
/*
* Are we booted from a PROM Of-type client-interface ?
*/
@@ -1322,6 +1360,19 @@ _INIT_STATIC(__boot_from_prom)
trap
_STATIC(__after_prom_start)
+ bl .reloc_offset
+ mr r26,r3
+#ifdef CONFIG_RELOCATABLE_PPC64
+ /*
+ * If its a relocatable kernel, no need to copy the kernel
+ * to PHYSICAL_START. Continue running from the same location
+ */
+ LOAD_REG_IMMEDIATE(r27, reloc_delta)
+ add r27,r27,r26
+ ld r28,0(r27)
+ cmpdi r28,0
+ bne .start_here_multiplatform
+#endif
/*
* We need to run with __start at physical address PHYSICAL_START.
@@ -1335,8 +1386,6 @@ _STATIC(__after_prom_start)
* r26 == relocation offset
* r27 == KERNELBASE
*/
- bl .reloc_offset
- mr r26,r3
LOAD_REG_IMMEDIATE(r27, KERNELBASE)
LOAD_REG_IMMEDIATE(r3, PHYSICAL_START) /* target addr */
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 631dfd6..09ce39d 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -43,7 +43,7 @@ int default_machine_kexec_prepare(struct kimage *image)
* overlaps kernel static data or bss.
*/
for (i = 0; i < image->nr_segments; i++)
- if (image->segment[i].mem < __pa(_end))
+ if (image->segment[i].mem < (__pa(_end) + kernel_base))
return -ETXTBSY;
/*
@@ -317,7 +317,7 @@ static void __init export_htab_values(void)
if (!node)
return;
- kernel_end = __pa(_end);
+ kernel_end = __pa(_end) + kernel_base;
prom_add_property(node, &kernel_end_prop);
/* On machines with no htab htab_address is NULL */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 1ea8c8d..1b67219 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -91,11 +91,9 @@ extern const struct linux_logo logo_linux_clut224;
* fortunately don't get interpreted as two arguments).
*/
#ifdef CONFIG_PPC64
-#define RELOC(x) (*PTRRELOC(&(x)))
#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
#define OF_WORKAROUNDS 0
#else
-#define RELOC(x) (x)
#define ADDR(x) (u32) (x)
#define OF_WORKAROUNDS of_workarounds
int of_workarounds;
@@ -1073,7 +1071,12 @@ static void __init prom_init_mem(void)
}
}
+#ifndef CONFIG_RELOCATABLE_PPC64
RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
+#else
+ RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000 +
+ RELOC(reloc_delta));
+#endif
/* Check if we have an initrd after the kernel, if we do move our bottom
* point to after it
@@ -1337,10 +1340,19 @@ static void __init prom_hold_cpus(void)
unsigned int cpu_threads, hw_cpu_num;
int propsize;
struct prom_t *_prom = &RELOC(prom);
+
+#ifndef CONFIG_RELOCATABLE_PPC64
unsigned long *spinloop
= (void *) LOW_ADDR(__secondary_hold_spinloop);
unsigned long *acknowledge
= (void *) LOW_ADDR(__secondary_hold_acknowledge);
+#else
+ unsigned long *spinloop
+ = (void *) &__secondary_hold_spinloop;
+ unsigned long *acknowledge
+ = (void *) &__secondary_hold_acknowledge;
+#endif
+
#ifdef CONFIG_PPC64
/* __secondary_hold is actually a descriptor, not the text address */
unsigned long secondary_hold
@@ -2402,8 +2414,15 @@ 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);
+ if (RELOC(of_platform) != PLATFORM_POWERMAC) {
+#ifdef CONFIG_RELOCATABLE_PPC64
+ if (RELOC(reloc_delta))
+ copy_and_flush(0, KERNELBASE + RELOC(reloc_delta),
+ 0x100, 0);
+ else
+#endif
+ copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
+ }
/*
* Do early parsing of command line
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index 2c7e8e8..3cc7e24 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
_end enter_prom memcpy memset reloc_offset __secondary_hold
__secondary_hold_acknowledge __secondary_hold_spinloop __start
strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
-reloc_got2 kernstart_addr"
+reloc_got2 kernstart_addr reloc_delta"
NM="$1"
OBJ="$2"
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 04d8de9..91fab43 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -208,7 +208,6 @@ void __init early_setup(unsigned long dt_ptr)
/* Probe the machine type */
probe_machine();
-
setup_kdump_trampoline();
DBG("Found, Initializing memory management...\n");
@@ -526,9 +525,9 @@ void __init setup_arch(char **cmdline_p)
if (ppc_md.panic)
setup_panic();
- init_mm.start_code = (unsigned long)_stext;
+ init_mm.start_code = (unsigned long)_stext + kernel_base;
init_mm.end_code = (unsigned long) _etext;
- init_mm.end_data = (unsigned long) _edata;
+ init_mm.end_data = (unsigned long) _edata + kernel_base;
init_mm.brk = klimit;
irqstack_early_init();
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 6ef63ca..1b908d4 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -79,10 +79,11 @@ phys_addr_t kernstart_addr;
void free_initmem(void)
{
- unsigned long addr;
+ unsigned long long addr, eaddr;
- addr = (unsigned long)__init_begin;
- for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
+ addr = (unsigned long long )__init_begin + kernel_base;
+ eaddr = (unsigned long long ) __init_end + kernel_base;
+ for (; addr < eaddr; addr += PAGE_SIZE) {
memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
ClearPageReserved(virt_to_page(addr));
init_page_count(virt_to_page(addr));
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 776ba6a..f727de6 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -401,7 +401,8 @@ void __init mem_init(void)
}
}
- codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
+ codesize = (unsigned long)&_sdata - (unsigned long)&_stext
+ + kernel_base;
datasize = (unsigned long)&_edata - (unsigned long)&_sdata;
initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index eb3bd2e..4d7aa4f 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -39,6 +39,8 @@
#define OF_DT_VERSION 0x10
+extern unsigned long reloc_delta, kernel_base;
+
/*
* This is what gets passed to the kernel by prom_init or kexec
*
diff --git a/include/asm-powerpc/sections.h b/include/asm-powerpc/sections.h
index 916018e..f19dab3 100644
--- a/include/asm-powerpc/sections.h
+++ b/include/asm-powerpc/sections.h
@@ -7,10 +7,12 @@
#ifdef __powerpc64__
extern char _end[];
+extern unsigned long kernel_base;
static inline int in_kernel_text(unsigned long addr)
{
- if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end)
+ if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end
+ + kernel_base)
return 1;
return 0;
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 0c12c66..4f98967 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -534,6 +534,11 @@ extern unsigned long add_reloc_offset(unsigned long);
extern void reloc_got2(unsigned long);
#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
+#ifdef CONFIG_PPC64
+#define RELOC(x) (*PTRRELOC(&(x)))
+#else
+#define RELOC(x) (x)
+#endif
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
extern void account_system_vtime(struct task_struct *);
--
1.5.4
next prev parent reply other threads:[~2008-07-21 19:23 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-17 18:33 [RFC v3 PATCH 0/4] Relocatable kernel support for PPC64 Mohan Kumar M
2008-07-17 18:40 ` [RFC v3 PATCH 1/4] Extract list of relocation offsets Mohan Kumar M
2008-07-17 20:06 ` Benjamin Herrenschmidt
2008-07-18 5:32 ` Mohan Kumar M
2008-07-18 17:00 ` Milton Miller
2008-07-21 19:17 ` Mohan Kumar M
2008-07-22 6:29 ` Paul Mackerras
2008-07-22 7:58 ` Mohan Kumar M
2008-07-21 19:20 ` [RFC v3 PATCH 2/4] Build files needed for relocation Mohan Kumar M
2008-07-21 19:21 ` [RFC v3 PATCH 3/4] Apply relocation Mohan Kumar M
2008-07-21 19:23 ` Mohan Kumar M [this message]
2008-07-21 19:25 ` [RFC v3 PATCH 5/4] Relocation support for kdump kernel Mohan Kumar M
2008-07-21 19:26 ` [RFC v3 PATCH 6/4] Use LOAD_REG_IMMEDIATE macros Mohan Kumar M
2008-07-22 2:03 ` Paul Mackerras
2008-07-22 4:37 ` Mohan Kumar M
2008-07-22 6:37 ` Paul Mackerras
2008-07-22 17:13 ` Segher Boessenkool
2008-07-17 18:42 ` [RFC v3 PATCH 2/4] Build files needed for relocation support Mohan Kumar M
2008-07-17 18:45 ` [RFC v3 PATCH 3/4] Apply relocation info to vmlinux Mohan Kumar M
2008-07-17 18:48 ` [RFC v3 PATCH 4/4] Relocation support Mohan Kumar M
2008-07-18 17:48 ` Segher Boessenkool
2008-07-21 9:11 ` Mohan Kumar M
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4884E238.8000504@in.ibm.com \
--to=mohan@in.ibm.com \
--cc=linuxppc-dev@ozlabs.org \
--cc=miltonm@bga.com \
--cc=naren@linux.vnet.ibm.com \
--cc=paulus@samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).