aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2012-11-26 12:41:08 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-01-10 01:00:31 -0500
commit1fbe9cf2598dae3bd464d860bd89c67b1ff8682b (patch)
treec07f1fe789777669466bc3077a5f0afa70cf83b6 /arch/powerpc
parent5827d4165ac608d7c26fa68701391e80824ee5c9 (diff)
powerpc: Build kernel with -mcmodel=medium
Finally remove the two level TOC and build with -mcmodel=medium. Unfortunately we can't build modules with -mcmodel=medium due to the tricks the kernel module loader plays with percpu data: # -mcmodel=medium breaks modules because it uses 32bit offsets from # the TOC pointer to create pointers where possible. Pointers into the # percpu data area are created by this method. # # The kernel module loader relocates the percpu data section from the # original location (starting with 0xd...) to somewhere in the base # kernel percpu data space (starting with 0xc...). We need a full # 64bit relocation for this to work, hence -mcmodel=large. On older kernels we fall back to the two level TOC (-mminimal-toc) Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Makefile19
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/head_64.S15
-rw-r--r--arch/powerpc/kernel/module_64.c30
-rw-r--r--arch/powerpc/lib/Makefile2
-rw-r--r--arch/powerpc/mm/Makefile2
-rw-r--r--arch/powerpc/oprofile/Makefile2
-rw-r--r--arch/powerpc/platforms/pseries/Makefile2
-rw-r--r--arch/powerpc/platforms/wsp/Makefile2
-rw-r--r--arch/powerpc/sysdev/Makefile2
-rw-r--r--arch/powerpc/xmon/Makefile2
11 files changed, 69 insertions, 11 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 78c2b024371a..31d8965e0847 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -67,7 +67,24 @@ LDFLAGS_vmlinux-y := -Bstatic
67LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie 67LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie
68LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y) 68LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y)
69 69
70CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=no -mcall-aixdesc 70ifeq ($(CONFIG_PPC64),y)
71ifeq ($(call cc-option-yn,-mcmodel=medium),y)
72 # -mcmodel=medium breaks modules because it uses 32bit offsets from
73 # the TOC pointer to create pointers where possible. Pointers into the
74 # percpu data area are created by this method.
75 #
76 # The kernel module loader relocates the percpu data section from the
77 # original location (starting with 0xd...) to somewhere in the base
78 # kernel percpu data space (starting with 0xc...). We need a full
79 # 64bit relocation for this to work, hence -mcmodel=large.
80 KBUILD_CFLAGS_MODULE += -mcmodel=large
81else
82 export NO_MINIMAL_TOC := -mno-minimal-toc
83endif
84endif
85
86CFLAGS-$(CONFIG_PPC64) := -mtraceback=no -mcall-aixdesc
87CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc)
71CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple 88CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
72 89
73CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,-mtune=power4) 90CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,-mtune=power4)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2f6ef4ed5abf..b4f0e360e414 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -7,7 +7,7 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
7subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror 7subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
8 8
9ifeq ($(CONFIG_PPC64),y) 9ifeq ($(CONFIG_PPC64),y)
10CFLAGS_prom_init.o += -mno-minimal-toc 10CFLAGS_prom_init.o += $(NO_MINIMAL_TOC)
11endif 11endif
12ifeq ($(CONFIG_PPC32),y) 12ifeq ($(CONFIG_PPC32),y)
13CFLAGS_prom_init.o += -fPIC 13CFLAGS_prom_init.o += -fPIC
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 116f0868695b..1697a25ebe91 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -169,6 +169,7 @@ _GLOBAL(generic_secondary_thread_init)
169 169
170 /* get a valid TOC pointer, wherever we're mapped at */ 170 /* get a valid TOC pointer, wherever we're mapped at */
171 bl .relative_toc 171 bl .relative_toc
172 tovirt(r2,r2)
172 173
173#ifdef CONFIG_PPC_BOOK3E 174#ifdef CONFIG_PPC_BOOK3E
174 /* Book3E initialization */ 175 /* Book3E initialization */
@@ -195,6 +196,7 @@ _GLOBAL(generic_secondary_smp_init)
195 196
196 /* get a valid TOC pointer, wherever we're mapped at */ 197 /* get a valid TOC pointer, wherever we're mapped at */
197 bl .relative_toc 198 bl .relative_toc
199 tovirt(r2,r2)
198 200
199#ifdef CONFIG_PPC_BOOK3E 201#ifdef CONFIG_PPC_BOOK3E
200 /* Book3E initialization */ 202 /* Book3E initialization */
@@ -531,6 +533,7 @@ _GLOBAL(pmac_secondary_start)
531 533
532 /* get TOC pointer (real address) */ 534 /* get TOC pointer (real address) */
533 bl .relative_toc 535 bl .relative_toc
536 tovirt(r2,r2)
534 537
535 /* Copy some CPU settings from CPU 0 */ 538 /* Copy some CPU settings from CPU 0 */
536 bl .__restore_cpu_ppc970 539 bl .__restore_cpu_ppc970
@@ -665,6 +668,13 @@ _GLOBAL(enable_64b_mode)
665 * This puts the TOC pointer into r2, offset by 0x8000 (as expected 668 * This puts the TOC pointer into r2, offset by 0x8000 (as expected
666 * by the toolchain). It computes the correct value for wherever we 669 * by the toolchain). It computes the correct value for wherever we
667 * are running at the moment, using position-independent code. 670 * are running at the moment, using position-independent code.
671 *
672 * Note: The compiler constructs pointers using offsets from the
673 * TOC in -mcmodel=medium mode. After we relocate to 0 but before
674 * the MMU is on we need our TOC to be a virtual address otherwise
675 * these pointers will be real addresses which may get stored and
676 * accessed later with the MMU on. We use tovirt() at the call
677 * sites to handle this.
668 */ 678 */
669_GLOBAL(relative_toc) 679_GLOBAL(relative_toc)
670 mflr r0 680 mflr r0
@@ -681,8 +691,9 @@ p_toc: .llong __toc_start + 0x8000 - 0b
681 * This is where the main kernel code starts. 691 * This is where the main kernel code starts.
682 */ 692 */
683_INIT_STATIC(start_here_multiplatform) 693_INIT_STATIC(start_here_multiplatform)
684 /* set up the TOC (real address) */ 694 /* set up the TOC */
685 bl .relative_toc 695 bl .relative_toc
696 tovirt(r2,r2)
686 697
687 /* Clear out the BSS. It may have been done in prom_init, 698 /* Clear out the BSS. It may have been done in prom_init,
688 * already but that's irrelevant since prom_init will soon 699 * already but that's irrelevant since prom_init will soon
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 9f44a775a106..6ee59a0eb268 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -386,6 +386,14 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
386 | (value & 0xffff); 386 | (value & 0xffff);
387 break; 387 break;
388 388
389 case R_PPC64_TOC16_LO:
390 /* Subtract TOC pointer */
391 value -= my_r2(sechdrs, me);
392 *((uint16_t *) location)
393 = (*((uint16_t *) location) & ~0xffff)
394 | (value & 0xffff);
395 break;
396
389 case R_PPC64_TOC16_DS: 397 case R_PPC64_TOC16_DS:
390 /* Subtract TOC pointer */ 398 /* Subtract TOC pointer */
391 value -= my_r2(sechdrs, me); 399 value -= my_r2(sechdrs, me);
@@ -399,6 +407,28 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
399 | (value & 0xfffc); 407 | (value & 0xfffc);
400 break; 408 break;
401 409
410 case R_PPC64_TOC16_LO_DS:
411 /* Subtract TOC pointer */
412 value -= my_r2(sechdrs, me);
413 if ((value & 3) != 0) {
414 printk("%s: bad TOC16_LO_DS relocation (%lu)\n",
415 me->name, value);
416 return -ENOEXEC;
417 }
418 *((uint16_t *) location)
419 = (*((uint16_t *) location) & ~0xfffc)
420 | (value & 0xfffc);
421 break;
422
423 case R_PPC64_TOC16_HA:
424 /* Subtract TOC pointer */
425 value -= my_r2(sechdrs, me);
426 value = ((value + 0x8000) >> 16);
427 *((uint16_t *) location)
428 = (*((uint16_t *) location) & ~0xffff)
429 | (value & 0xffff);
430 break;
431
402 case R_PPC_REL24: 432 case R_PPC_REL24:
403 /* FIXME: Handle weak symbols here --RR */ 433 /* FIXME: Handle weak symbols here --RR */
404 if (sym->st_shndx == SHN_UNDEF) { 434 if (sym->st_shndx == SHN_UNDEF) {
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 746e0c895cd7..fa48a4cc19a3 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -4,7 +4,7 @@
4 4
5subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror 5subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
6 6
7ccflags-$(CONFIG_PPC64) := -mno-minimal-toc 7ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
8 8
9CFLAGS_REMOVE_code-patching.o = -pg 9CFLAGS_REMOVE_code-patching.o = -pg
10CFLAGS_REMOVE_feature-fixups.o = -pg 10CFLAGS_REMOVE_feature-fixups.o = -pg
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 3787b61f7d20..cf16b5733eaa 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -4,7 +4,7 @@
4 4
5subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror 5subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
6 6
7ccflags-$(CONFIG_PPC64) := -mno-minimal-toc 7ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
8 8
9obj-y := fault.o mem.o pgtable.o gup.o \ 9obj-y := fault.o mem.o pgtable.o gup.o \
10 init_$(CONFIG_WORD_SIZE).o \ 10 init_$(CONFIG_WORD_SIZE).o \
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 73456c4cec28..751ec7bd5018 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -1,6 +1,6 @@
1subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror 1subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
2 2
3ccflags-$(CONFIG_PPC64) := -mno-minimal-toc 3ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
4 4
5obj-$(CONFIG_OPROFILE) += oprofile.o 5obj-$(CONFIG_OPROFILE) += oprofile.o
6 6
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 890622b87c8f..53866e537a92 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -1,4 +1,4 @@
1ccflags-$(CONFIG_PPC64) := -mno-minimal-toc 1ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
2ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG 2ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG
3 3
4obj-y := lpar.o hvCall.o nvram.o reconfig.o \ 4obj-y := lpar.o hvCall.o nvram.o reconfig.o \
diff --git a/arch/powerpc/platforms/wsp/Makefile b/arch/powerpc/platforms/wsp/Makefile
index 56817ac98fc9..162fc60125a2 100644
--- a/arch/powerpc/platforms/wsp/Makefile
+++ b/arch/powerpc/platforms/wsp/Makefile
@@ -1,4 +1,4 @@
1ccflags-y += -mno-minimal-toc 1ccflags-y += $(NO_MINIMAL_TOC)
2 2
3obj-y += setup.o ics.o wsp.o 3obj-y += setup.o ics.o wsp.o
4obj-$(CONFIG_PPC_PSR2) += psr2.o 4obj-$(CONFIG_PPC_PSR2) += psr2.o
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index f44f09f3d527..eca3d19304c7 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -1,6 +1,6 @@
1subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror 1subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
2 2
3ccflags-$(CONFIG_PPC64) := -mno-minimal-toc 3ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
4 4
5mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o 5mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
6obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) 6obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index b49fdbd15808..1278788d96e3 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -4,7 +4,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
4 4
5GCOV_PROFILE := n 5GCOV_PROFILE := n
6 6
7ccflags-$(CONFIG_PPC64) := -mno-minimal-toc 7ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
8 8
9obj-y += xmon.o nonstdio.o 9obj-y += xmon.o nonstdio.o
10 10