Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Oct 2016 21:26:58 +0000 (14:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Oct 2016 21:26:58 +0000 (14:26 -0700)
Pull kbuild updates from Michal Marek:

 - EXPORT_SYMBOL for asm source by Al Viro.

   This does bring a regression, because genksyms no longer generates
   checksums for these symbols (CONFIG_MODVERSIONS). Nick Piggin is
   working on a patch to fix this.

   Plus, we are talking about functions like strcpy(), which rarely
   change prototypes.

 - Fixes for PPC fallout of the above by Stephen Rothwell and Nick
   Piggin

 - fixdep speedup by Alexey Dobriyan.

 - preparatory work by Nick Piggin to allow architectures to build with
   -ffunction-sections, -fdata-sections and --gc-sections

 - CONFIG_THIN_ARCHIVES support by Stephen Rothwell

 - fix for filenames with colons in the initramfs source by me.

* 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild: (22 commits)
  initramfs: Escape colons in depfile
  ppc: there is no clear_pages to export
  powerpc/64: whitelist unresolved modversions CRCs
  kbuild: -ffunction-sections fix for archs with conflicting sections
  kbuild: add arch specific post-link Makefile
  kbuild: allow archs to select link dead code/data elimination
  kbuild: allow architectures to use thin archives instead of ld -r
  kbuild: Regenerate genksyms lexer
  kbuild: genksyms fix for typeof handling
  fixdep: faster CONFIG_ search
  ia64: move exports to definitions
  sparc32: debride memcpy.S a bit
  [sparc] unify 32bit and 64bit string.h
  sparc: move exports to definitions
  ppc: move exports to definitions
  arm: move exports to definitions
  s390: move exports to definitions
  m68k: move exports to definitions
  alpha: move exports to actual definitions
  x86: move exports to actual definitions
  ...

34 files changed:
1  2 
Makefile
arch/Kconfig
arch/arm/lib/delay.c
arch/arm/mach-imx/Makefile
arch/m68k/kernel/Makefile
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/fpu.S
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/vector.S
arch/powerpc/lib/Makefile
arch/powerpc/lib/checksum_32.S
arch/powerpc/lib/copyuser_64.S
arch/powerpc/lib/mem_64.S
arch/s390/kernel/Makefile
arch/x86/entry/entry_32.S
arch/x86/entry/entry_64.S
arch/x86/kernel/Makefile
arch/x86/kernel/head_32.S
arch/x86/kernel/head_64.S
arch/x86/lib/hweight.S
arch/x86/lib/memcpy_64.S
include/asm-generic/vmlinux.lds.h
include/linux/compiler.h
include/linux/export.h
include/linux/init.h

diff --combined Makefile
+++ b/Makefile
@@@ -1,7 -1,7 +1,7 @@@
  VERSION = 4
  PATCHLEVEL = 8
  SUBLEVEL = 0
 -EXTRAVERSION = -rc1
 +EXTRAVERSION =
  NAME = Psychotic Stoned Sheep
  
  # *DOCUMENTATION*
@@@ -621,8 -621,12 +621,13 @@@ include arch/$(SRCARCH)/Makefil
  
  KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
  KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,)
 +KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
  
+ ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
+ KBUILD_CFLAGS += $(call cc-option,-ffunction-sections,)
+ KBUILD_CFLAGS += $(call cc-option,-fdata-sections,)
+ endif
  ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
  KBUILD_CFLAGS += -Os
  else
@@@ -636,6 -640,13 +641,6 @@@ endi
  # Tell gcc to never replace conditional load with a non-conditional one
  KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0)
  
 -PHONY += gcc-plugins
 -gcc-plugins: scripts_basic
 -ifdef CONFIG_GCC_PLUGINS
 -      $(Q)$(MAKE) $(build)=scripts/gcc-plugins
 -endif
 -      @:
 -
  include scripts/Makefile.gcc-plugins
  
  ifdef CONFIG_READABLE_ASM
@@@ -803,6 -814,10 +808,10 @@@ LDFLAGS_BUILD_ID = $(patsubst -Wl$(comm
  KBUILD_LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
  LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
  
+ ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
+ LDFLAGS_vmlinux       += $(call ld-option, --gc-sections,)
+ endif
  ifeq ($(CONFIG_STRIP_ASM_SYMS),y)
  LDFLAGS_vmlinux       += $(call ld-option, -X,)
  endif
@@@ -942,9 -957,12 +951,12 @@@ endi
  include/generated/autoksyms.h: FORCE
        $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh true
  
- # Final link of vmlinux
-       cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux)
- quiet_cmd_link-vmlinux = LINK    $@
+ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
+ # Final link of vmlinux with optional arch pass after final link
+     cmd_link-vmlinux =                                                 \
+       $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) ;       \
+       $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
  
  vmlinux: scripts/link-vmlinux.sh vmlinux_prereq $(vmlinux-deps) FORCE
        +$(call if_changed,link-vmlinux)
@@@ -1271,6 -1289,7 +1283,7 @@@ $(clean-dirs)
  
  vmlinuxclean:
        $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
+       $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean)
  
  clean: archclean vmlinuxclean
  
@@@ -1426,7 -1445,7 +1439,7 @@@ $(help-board-dirs): help-%
  
  # Documentation targets
  # ---------------------------------------------------------------------------
 -DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs
 +DOC_TARGETS := xmldocs sgmldocs psdocs latexdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs
  PHONY += $(DOC_TARGETS)
  $(DOC_TARGETS): scripts_basic FORCE
        $(Q)$(MAKE) $(build)=scripts build_docproc build_check-lc_ctype
diff --combined arch/Kconfig
@@@ -336,6 -336,17 +336,6 @@@ config HAVE_ARCH_SECCOMP_FILTE
            results in the system call being skipped immediately.
          - seccomp syscall wired up
  
 -        For best performance, an arch should use seccomp_phase1 and
 -        seccomp_phase2 directly.  It should call seccomp_phase1 for all
 -        syscalls if TIF_SECCOMP is set, but seccomp_phase1 does not
 -        need to be called from a ptrace-safe context.  It must then
 -        call seccomp_phase2 if seccomp_phase1 returns anything other
 -        than SECCOMP_PHASE1_OK or SECCOMP_PHASE1_SKIP.
 -
 -        As an additional optimization, an arch may provide seccomp_data
 -        directly to seccomp_phase1; this avoids multiple calls
 -        to the syscall_xyz helpers for every syscall.
 -
  config SECCOMP_FILTER
        def_bool y
        depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET
@@@ -450,15 -461,27 +450,36 @@@ config CC_STACKPROTECTOR_STRON
  
  endchoice
  
+ config THIN_ARCHIVES
+       bool
+       help
+         Select this if the architecture wants to use thin archives
+         instead of ld -r to create the built-in.o files.
+ config LD_DEAD_CODE_DATA_ELIMINATION
+       bool
+       help
+         Select this if the architecture wants to do dead code and
+         data elimination with the linker by compiling with
+         -ffunction-sections -fdata-sections and linking with
+         --gc-sections.
+         This requires that the arch annotates or otherwise protects
+         its external entry points from being discarded. Linker scripts
+         must also merge .text.*, .data.*, and .bss.* correctly into
+         output sections. Care must be taken not to pull in unrelated
+         sections (e.g., '.text.init'). Typically '.' in section names
+         is used to distinguish them from label names / C identifiers.
 +config HAVE_ARCH_WITHIN_STACK_FRAMES
 +      bool
 +      help
 +        An architecture should select this if it can walk the kernel stack
 +        frames to determine if an object is part of either the arguments
 +        or local variables (i.e. that it excludes saved return addresses,
 +        and similar) by implementing an inline arch_within_stack_frames(),
 +        which is used by CONFIG_HARDENED_USERCOPY.
 +
  config HAVE_CONTEXT_TRACKING
        bool
        help
@@@ -696,38 -719,4 +717,38 @@@ config ARCH_NO_COHERENT_DMA_MMA
  config CPU_NO_EFFICIENT_FFS
        def_bool n
  
 +config HAVE_ARCH_VMAP_STACK
 +      def_bool n
 +      help
 +        An arch should select this symbol if it can support kernel stacks
 +        in vmalloc space.  This means:
 +
 +        - vmalloc space must be large enough to hold many kernel stacks.
 +          This may rule out many 32-bit architectures.
 +
 +        - Stacks in vmalloc space need to work reliably.  For example, if
 +          vmap page tables are created on demand, either this mechanism
 +          needs to work while the stack points to a virtual address with
 +          unpopulated page tables or arch code (switch_to() and switch_mm(),
 +          most likely) needs to ensure that the stack's page table entries
 +          are populated before running on a possibly unpopulated stack.
 +
 +        - If the stack overflows into a guard page, something reasonable
 +          should happen.  The definition of "reasonable" is flexible, but
 +          instantly rebooting without logging anything would be unfriendly.
 +
 +config VMAP_STACK
 +      default y
 +      bool "Use a virtually-mapped stack"
 +      depends on HAVE_ARCH_VMAP_STACK && !KASAN
 +      ---help---
 +        Enable this if you want the use virtually-mapped kernel stacks
 +        with guard pages.  This causes kernel stack overflows to be
 +        caught immediately rather than causing difficult-to-diagnose
 +        corruption.
 +
 +        This is presently incompatible with KASAN because KASAN expects
 +        the stack to map directly to the KASAN shadow map using a formula
 +        that is incorrect if the stack is in vmalloc space.
 +
  source "kernel/gcov/Kconfig"
diff --combined arch/arm/lib/delay.c
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
+ #include <linux/export.h>
  #include <linux/timex.h>
  
  /*
   * Default to the loop-based delay implementation.
   */
 -struct arm_delay_ops arm_delay_ops = {
 +struct arm_delay_ops arm_delay_ops __ro_after_init = {
        .delay          = __loop_delay,
        .const_udelay   = __loop_const_udelay,
        .udelay         = __loop_udelay,
  };
+ EXPORT_SYMBOL(arm_delay_ops);
  
  static const struct delay_timer *delay_timer;
  static bool delay_calibrated;
@@@ -1,5 -1,6 +1,5 @@@
  obj-y := cpu.o system.o irq-common.o
  
 -obj-$(CONFIG_SOC_IMX1) += mm-imx1.o
  obj-$(CONFIG_SOC_IMX21) += mm-imx21.o
  
  obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o pm-imx25.o
@@@ -27,14 -28,17 +27,13 @@@ obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.
  obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
  obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
  obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
 +obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o
  endif
  
  ifdef CONFIG_SND_IMX_SOC
  obj-y += ssi-fiq.o
- obj-y += ssi-fiq-ksym.o
  endif
  
 -# i.MX1 based machines
 -obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
 -obj-$(CONFIG_MACH_APF9328) += mach-apf9328.o
 -obj-$(CONFIG_MACH_IMX1_DT) += imx1-dt.o
 -
  # i.MX21 based machines
  obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
  
@@@ -88,7 -92,6 +87,7 @@@ obj-$(CONFIG_SOC_IMX53) += suspend-imx5
  endif
  obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
  
 +obj-$(CONFIG_SOC_IMX1) += mach-imx1.o
  obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
  obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
  obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
@@@ -13,7 -13,7 +13,7 @@@ extra-$(CONFIG_SUN3X) := head.
  extra-$(CONFIG_SUN3)  := sun3-head.o
  extra-y                       += vmlinux.lds
  
- obj-y := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o
+ obj-y := entry.o irq.o module.o process.o ptrace.o
  obj-y += setup.o signal.o sys_m68k.o syscalltable.o time.o traps.o
  
  obj-$(CONFIG_MMU_MOTOROLA) += ints.o vectors.o
@@@ -24,7 -24,6 +24,7 @@@ obj-$(CONFIG_HAS_DMA) += dma.
  
  obj-$(CONFIG_KEXEC)           += machine_kexec.o relocate_kernel.o
  obj-$(CONFIG_BOOTINFO_PROC)   += bootinfo_proc.o
 +obj-$(CONFIG_UBOOT)           += uboot.o
  
  obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
  
@@@ -31,7 -31,8 +31,7 @@@ obj-y                         := cputable.o ptrace.o syscall
                                   process.o systbl.o idle.o \
                                   signal.o sysfs.o cacheinfo.o time.o \
                                   prom.o traps.o setup-common.o \
 -                                 udbg.o misc.o io.o dma.o \
 -                                 misc_$(CONFIG_WORD_SIZE).o \
 +                                 udbg.o misc.o io.o dma.o misc_$(BITS).o \
                                   of_platform.o prom_parse.o
  obj-$(CONFIG_PPC64)           += setup_64.o sys_ppc32.o \
                                   signal_64.o ptrace32.o \
@@@ -40,7 -41,7 +40,7 @@@ obj-$(CONFIG_VDSO32)          += vdso32
  obj-$(CONFIG_HAVE_HW_BREAKPOINT)      += hw_breakpoint.o
  obj-$(CONFIG_PPC_BOOK3S_64)   += cpu_setup_ppc970.o cpu_setup_pa6t.o
  obj-$(CONFIG_PPC_BOOK3S_64)   += cpu_setup_power.o
 -obj-$(CONFIG_PPC_BOOK3S_64)   += mce.o mce_power.o hmi.o
 +obj-$(CONFIG_PPC_BOOK3S_64)   += mce.o mce_power.o
  obj-$(CONFIG_PPC_BOOK3E_64)   += exceptions-64e.o idle_book3e.o
  obj-$(CONFIG_PPC64)           += vdso64/
  obj-$(CONFIG_ALTIVEC)         += vecemu.o
@@@ -69,31 -70,27 +69,27 @@@ obj-$(CONFIG_HIBERNATION)  += swsusp.o s
  ifeq ($(CONFIG_FSL_BOOKE),y)
  obj-$(CONFIG_HIBERNATION)     += swsusp_booke.o
  else
 -obj-$(CONFIG_HIBERNATION)     += swsusp_$(CONFIG_WORD_SIZE).o
 +obj-$(CONFIG_HIBERNATION)     += swsusp_$(BITS).o
  endif
  obj64-$(CONFIG_HIBERNATION)   += swsusp_asm64.o
 -obj-$(CONFIG_MODULES)         += module.o module_$(CONFIG_WORD_SIZE).o
 +obj-$(CONFIG_MODULES)         += module.o module_$(BITS).o
  obj-$(CONFIG_44x)             += cpu_setup_44x.o
  obj-$(CONFIG_PPC_FSL_BOOK3E)  += cpu_setup_fsl_booke.o
  obj-$(CONFIG_PPC_DOORBELL)    += dbell.o
  obj-$(CONFIG_JUMP_LABEL)      += jump_label.o
  
 -extra-y                               := head_$(CONFIG_WORD_SIZE).o
 +extra-y                               := head_$(BITS).o
  extra-$(CONFIG_40x)           := head_40x.o
  extra-$(CONFIG_44x)           := head_44x.o
  extra-$(CONFIG_FSL_BOOKE)     := head_fsl_booke.o
  extra-$(CONFIG_8xx)           := head_8xx.o
  extra-y                               += vmlinux.lds
  
 -obj-$(CONFIG_RELOCATABLE)     += reloc_$(CONFIG_WORD_SIZE).o
 +obj-$(CONFIG_RELOCATABLE)     += reloc_$(BITS).o
  
  obj-$(CONFIG_PPC32)           += entry_32.o setup_32.o
  obj-$(CONFIG_PPC64)           += dma-iommu.o iommu.o
  obj-$(CONFIG_KGDB)            += kgdb.o
- obj-$(CONFIG_MODULES)         += ppc_ksyms.o
- ifeq ($(CONFIG_PPC32),y)
- obj-$(CONFIG_MODULES)         += ppc_ksyms_32.o
- endif
  obj-$(CONFIG_BOOTX_TEXT)      += btext.o
  obj-$(CONFIG_SMP)             += smp.o
  obj-$(CONFIG_KPROBES)         += kprobes.o
@@@ -103,11 -100,11 +99,11 @@@ obj-$(CONFIG_STACKTRACE) += stacktrace.
  obj-$(CONFIG_SWIOTLB)         += dma-swiotlb.o
  
  pci64-$(CONFIG_PPC64)         += pci_dn.o pci-hotplug.o isa-bridge.o
 -obj-$(CONFIG_PCI)             += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
 +obj-$(CONFIG_PCI)             += pci_$(BITS).o $(pci64-y) \
                                   pci-common.o pci_of_scan.o
  obj-$(CONFIG_PCI_MSI)         += msi.o
  obj-$(CONFIG_KEXEC)           += machine_kexec.o crash.o \
 -                                 machine_kexec_$(CONFIG_WORD_SIZE).o
 +                                 machine_kexec_$(BITS).o
  obj-$(CONFIG_AUDIT)           += audit.o
  obj64-$(CONFIG_AUDIT)         += compat_audit.o
  
@@@ -33,6 -33,7 +33,7 @@@
  #include <asm/unistd.h>
  #include <asm/ftrace.h>
  #include <asm/ptrace.h>
+ #include <asm/export.h>
  
  /*
   * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
@@@ -654,6 -655,7 +655,6 @@@ END_FTR_SECTION_IFSET(CPU_FTR_SPE
  #endif /* CONFIG_SMP */
  
        tophys(r0,r4)
 -      CLR_TOP32(r0)
        mtspr   SPRN_SPRG_THREAD,r0     /* Update current THREAD phys addr */
        lwz     r1,KSP(r4)      /* Load new stack pointer */
  
@@@ -1358,6 -1360,7 +1359,7 @@@ _GLOBAL(_mcount
        MCOUNT_RESTORE_FRAME
        bctr
  #endif
+ EXPORT_SYMBOL(_mcount)
  
  _GLOBAL(ftrace_stub)
        blr
@@@ -38,6 -38,7 +38,7 @@@
  #include <asm/context_tracking.h>
  #include <asm/tm.h>
  #include <asm/ppc-opcode.h>
+ #include <asm/export.h>
  
  /*
   * System calls.
@@@ -139,7 -140,7 +140,7 @@@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPL
  #ifdef CONFIG_PPC_BOOK3E
        wrteei  1
  #else
 -      ld      r11,PACAKMSR(r13)
 +      li      r11,MSR_RI
        ori     r11,r11,MSR_EE
        mtmsrd  r11,1
  #endif /* CONFIG_PPC_BOOK3E */
@@@ -195,6 -196,7 +196,6 @@@ system_call:                       /* label this so stack t
  #ifdef CONFIG_PPC_BOOK3E
        wrteei  0
  #else
 -      ld      r10,PACAKMSR(r13)
        /*
         * For performance reasons we clear RI the same time that we
         * clear EE. We only need to clear RI just before we restore r13
         * We have to be careful to restore RI if we branch anywhere from
         * here (eg syscall_exit_work).
         */
 -      li      r9,MSR_RI
 -      andc    r11,r10,r9
 +      li      r11,0
        mtmsrd  r11,1
  #endif /* CONFIG_PPC_BOOK3E */
  
  #endif
  2:    addi    r3,r1,STACK_FRAME_OVERHEAD
  #ifdef CONFIG_PPC_BOOK3S
 +      li      r10,MSR_RI
        mtmsrd  r10,1           /* Restore RI */
  #endif
        bl      restore_math
  #ifdef CONFIG_PPC_BOOK3S
 -      ld      r10,PACAKMSR(r13)
 -      li      r9,MSR_RI
 -      andc    r11,r10,r9 /* Re-clear RI */
 +      li      r11,0
        mtmsrd  r11,1
  #endif
        ld      r8,_MSR(r1)
@@@ -305,7 -309,6 +306,7 @@@ syscall_enosys
        
  syscall_exit_work:
  #ifdef CONFIG_PPC_BOOK3S
 +      li      r10,MSR_RI
        mtmsrd  r10,1           /* Restore RI */
  #endif
        /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr.
@@@ -352,7 -355,7 +353,7 @@@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR
  #ifdef CONFIG_PPC_BOOK3E
        wrteei  1
  #else
 -      ld      r10,PACAKMSR(r13)
 +      li      r10,MSR_RI
        ori     r10,r10,MSR_EE
        mtmsrd  r10,1
  #endif /* CONFIG_PPC_BOOK3E */
  tabort_syscall:
        /* Firstly we need to enable TM in the kernel */
        mfmsr   r10
 -      li      r13, 1
 -      rldimi  r10, r13, MSR_TM_LG, 63-MSR_TM_LG
 +      li      r9, 1
 +      rldimi  r10, r9, MSR_TM_LG, 63-MSR_TM_LG
        mtmsrd  r10, 0
  
        /* tabort, this dooms the transaction, nothing else */
 -      li      r13, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
 -      TABORT(R13)
 +      li      r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
 +      TABORT(R9)
  
        /*
         * Return directly to userspace. We have corrupted user register state,
         * resume after the tbegin of the aborted transaction with the
         * checkpointed register state.
         */
 -      li      r13, MSR_RI
 -      andc    r10, r10, r13
 +      li      r9, MSR_RI
 +      andc    r10, r10, r9
        mtmsrd  r10, 1
        mtspr   SPRN_SRR0, r11
        mtspr   SPRN_SRR1, r12
@@@ -617,7 -620,7 +618,7 @@@ _GLOBAL(ret_from_except_lite
  #ifdef CONFIG_PPC_BOOK3E
        wrteei  0
  #else
 -      ld      r10,PACAKMSR(r13) /* Get kernel MSR without EE */
 +      li      r10,MSR_RI
        mtmsrd  r10,1             /* Update machine state */
  #endif /* CONFIG_PPC_BOOK3E */
  
@@@ -749,7 -752,7 +750,7 @@@ resume_kernel
  #ifdef CONFIG_PPC_BOOK3E
        wrteei  0
  #else
 -      ld      r10,PACAKMSR(r13) /* Get kernel MSR without EE */
 +      li      r10,MSR_RI
        mtmsrd  r10,1             /* Update machine state */
  #endif /* CONFIG_PPC_BOOK3E */
  #endif /* CONFIG_PREEMPT */
@@@ -839,7 -842,8 +840,7 @@@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR
         * userspace and we take an exception after restoring r13,
         * we end up corrupting the userspace r13 value.
         */
 -      ld      r4,PACAKMSR(r13) /* Get kernel MSR without EE */
 -      andc    r4,r4,r0         /* r0 contains MSR_RI here */
 +      li      r4,0
        mtmsrd  r4,1
  
  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
@@@ -1177,6 -1181,7 +1178,7 @@@ _GLOBAL(enter_prom
  #ifdef CONFIG_DYNAMIC_FTRACE
  _GLOBAL(mcount)
  _GLOBAL(_mcount)
+ EXPORT_SYMBOL(_mcount)
        mflr    r12
        mtctr   r12
        mtlr    r0
@@@ -1413,6 -1418,7 +1415,7 @@@ livepatch_handler
  
  #else
  _GLOBAL_TOC(_mcount)
+ EXPORT_SYMBOL(_mcount)
        /* Taken from output of objdump from lib64/glibc */
        mflr    r3
        ld      r11, 0(r1)
@@@ -24,6 -24,7 +24,7 @@@
  #include <asm/ppc_asm.h>
  #include <asm/asm-offsets.h>
  #include <asm/ptrace.h>
+ #include <asm/export.h>
  
  #ifdef CONFIG_VSX
  #define __REST_32FPVSRS(n,c,base)                                     \
@@@ -50,6 -51,32 +51,6 @@@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
  #define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base)
  #define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base)
  
 -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 -/* void do_load_up_transact_fpu(struct thread_struct *thread)
 - *
 - * This is similar to load_up_fpu but for the transactional version of the FP
 - * register set.  It doesn't mess with the task MSR or valid flags.
 - * Furthermore, we don't do lazy FP with TM currently.
 - */
 -_GLOBAL(do_load_up_transact_fpu)
 -      mfmsr   r6
 -      ori     r5,r6,MSR_FP
 -#ifdef CONFIG_VSX
 -BEGIN_FTR_SECTION
 -      oris    r5,r5,MSR_VSX@h
 -END_FTR_SECTION_IFSET(CPU_FTR_VSX)
 -#endif
 -      SYNC
 -      MTMSRD(r5)
 -
 -      addi    r7,r3,THREAD_TRANSACT_FPSTATE
 -      lfd     fr0,FPSTATE_FPSCR(r7)
 -      MTFSF_L(fr0)
 -      REST_32FPVSRS(0, R4, R7)
 -
 -      blr
 -#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 -
  /*
   * Load state from memory into FP registers including FPSCR.
   * Assumes the caller has enabled FP in the MSR.
@@@ -59,6 -86,7 +60,7 @@@ _GLOBAL(load_fp_state
        MTFSF_L(fr0)
        REST_32FPVSRS(0, R4, R3)
        blr
+ EXPORT_SYMBOL(load_fp_state)
  
  /*
   * Store FP state into memory, including FPSCR
@@@ -69,6 -97,7 +71,7 @@@ _GLOBAL(store_fp_state
        mffs    fr0
        stfd    fr0,FPSTATE_FPSCR(r3)
        blr
+ EXPORT_SYMBOL(store_fp_state)
  
  /*
   * This task wants to use the FPU now.
@@@ -34,6 -34,7 +34,7 @@@
  #include <asm/ptrace.h>
  #include <asm/bug.h>
  #include <asm/kvm_book3s_asm.h>
+ #include <asm/export.h>
  
  /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
  #define LOAD_BAT(n, reg, RA, RB)      \
@@@ -266,6 -267,7 +267,6 @@@ __secondary_hold_acknowledge
  
  
  #define EXCEPTION_PROLOG_2    \
 -      CLR_TOP32(r11);         \
        stw     r10,_CCR(r11);          /* save registers */ \
        stw     r12,GPR12(r11); \
        stw     r9,GPR9(r11);   \
@@@ -738,6 -740,7 +739,7 @@@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_
  
        .globl mol_trampoline
        .set mol_trampoline, i0x2f00
+       EXPORT_SYMBOL(mol_trampoline)
  
        . = 0x3000
  
@@@ -861,6 -864,7 +863,6 @@@ __secondary_start
        /* ptr to phys current thread */
        tophys(r4,r2)
        addi    r4,r4,THREAD    /* phys address of our thread_struct */
 -      CLR_TOP32(r4)
        mtspr   SPRN_SPRG_THREAD,r4
        li      r3,0
        mtspr   SPRN_SPRG_RTAS,r3       /* 0 => not in RTAS */
@@@ -947,6 -951,7 +949,6 @@@ start_here
        /* ptr to phys current thread */
        tophys(r4,r2)
        addi    r4,r4,THREAD    /* init task's THREAD */
 -      CLR_TOP32(r4)
        mtspr   SPRN_SPRG_THREAD,r4
        li      r3,0
        mtspr   SPRN_SPRG_RTAS,r3       /* 0 => not in RTAS */
@@@ -1045,6 -1050,7 +1047,7 @@@ _ENTRY(switch_mmu_context
  4:    trap
        EMIT_BUG_ENTRY 4b,__FILE__,__LINE__,0
        blr
+ EXPORT_SYMBOL(switch_mmu_context)
  
  /*
   * An undocumented "feature" of 604e requires that the v bit
@@@ -1272,6 -1278,7 +1275,7 @@@ sdata
        .globl  empty_zero_page
  empty_zero_page:
        .space  4096
+ EXPORT_SYMBOL(empty_zero_page)
  
        .globl  swapper_pg_dir
  swapper_pg_dir:
@@@ -1285,6 -1292,7 +1289,7 @@@ intercept_table
        .long 0, 0, 0, 0, 0, 0, 0, 0
        .long 0, 0, 0, 0, 0, 0, 0, 0
        .long 0, 0, 0, 0, 0, 0, 0, 0
+ EXPORT_SYMBOL(intercept_table)
  
  /* Room for two PTE pointers, usually the kernel and current user pointers
   * to their respective root page table.
@@@ -28,7 -28,6 +28,7 @@@
  #include <asm/page.h>
  #include <asm/mmu.h>
  #include <asm/ppc_asm.h>
 +#include <asm/head-64.h>
  #include <asm/asm-offsets.h>
  #include <asm/bug.h>
  #include <asm/cputable.h>
@@@ -43,6 -42,7 +43,7 @@@
  #include <asm/hw_irq.h>
  #include <asm/cputhreads.h>
  #include <asm/ppc-opcode.h>
+ #include <asm/export.h>
  
  /* The physical memory is laid out such that the secondary processor
   * spin code sits at 0x0000...0x00ff. On server, the vectors follow
   *   2. The kernel is entered at __start
   */
  
 -      .text
 -      .globl  _stext
 -_stext:
 +OPEN_FIXED_SECTION(first_256B, 0x0, 0x100)
 +USE_FIXED_SECTION(first_256B)
 +      /*
 +       * Offsets are relative from the start of fixed section, and
 +       * first_256B starts at 0. Offsets are a bit easier to use here
 +       * than the fixed section entry macros.
 +       */
 +      . = 0x0
  _GLOBAL(__start)
        /* NOP this out unconditionally */
  BEGIN_FTR_SECTION
@@@ -110,7 -105,6 +111,7 @@@ __secondary_hold_acknowledge
        . = 0x5c
        .globl  __run_at_load
  __run_at_load:
 +DEFINE_FIXED_SYMBOL(__run_at_load)
        .long   0x72756e30      /* "run0" -- relocate to 0 by default */
  #endif
  
@@@ -140,7 -134,7 +141,7 @@@ __secondary_hold
        /* Tell the master cpu we're here */
        /* Relocation is off & we are located at an address less */
        /* than 0x100, so only need to grab low order offset.    */
 -      std     r24,__secondary_hold_acknowledge-_stext(0)
 +      std     r24,(ABS_ADDR(__secondary_hold_acknowledge))(0)
        sync
  
        li      r26,0
        tovirt(r26,r26)
  #endif
        /* All secondary cpus wait here until told to start. */
 -100:  ld      r12,__secondary_hold_spinloop-_stext(r26)
 +100:  ld      r12,(ABS_ADDR(__secondary_hold_spinloop))(r26)
        cmpdi   0,r12,0
        beq     100b
  
  #else
        BUG_OPCODE
  #endif
 +CLOSE_FIXED_SECTION(first_256B)
  
  /* This value is used to mark exception frames on the stack. */
        .section ".toc","aw"
  exception_marker:
        .tc     ID_72656773_68657265[TC],0x7265677368657265
 -      .text
 +      .previous
  
  /*
   * On server, we include the exception vectors code here as it
   */
  #ifdef CONFIG_PPC_BOOK3S
  #include "exceptions-64s.S"
 +#else
 +OPEN_TEXT_SECTION(0x100)
  #endif
  
 +USE_TEXT_SECTION()
 +
  #ifdef CONFIG_PPC_BOOK3E
  /*
   * The booting_thread_hwid holds the thread id we want to boot in cpu
@@@ -570,7 -559,7 +571,7 @@@ __after_prom_start
  #if defined(CONFIG_PPC_BOOK3E)
        tovirt(r26,r26)         /* on booke, we already run at PAGE_OFFSET */
  #endif
 -      lwz     r7,__run_at_load-_stext(r26)
 +      lwz     r7,(FIXED_SYMBOL_ABS_ADDR(__run_at_load))(r26)
  #if defined(CONFIG_PPC_BOOK3E)
        tophys(r26,r26)
  #endif
  #if defined(CONFIG_PPC_BOOK3E)
        tovirt(r26,r26)         /* on booke, we already run at PAGE_OFFSET */
  #endif
 -      lwz     r7,__run_at_load-_stext(r26)
 +      lwz     r7,(FIXED_SYMBOL_ABS_ADDR(__run_at_load))(r26)
        cmplwi  cr0,r7,1
        bne     3f
  
        sub     r5,r5,r11
  #else
        /* just copy interrupts */
 -      LOAD_REG_IMMEDIATE(r5, __end_interrupts - _stext)
 +      LOAD_REG_IMMEDIATE(r5, FIXED_SYMBOL_ABS_ADDR(__end_interrupts))
  #endif
        b       5f
  3:
  #endif
 -      lis     r5,(copy_to_here - _stext)@ha
 -      addi    r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
 +      /* # bytes of memory to copy */
 +      lis     r5,(ABS_ADDR(copy_to_here))@ha
 +      addi    r5,r5,(ABS_ADDR(copy_to_here))@l
  
        bl      copy_and_flush          /* copy the first n bytes        */
                                        /* this includes the code being  */
                                        /* executed here.                */
 -      addis   r8,r3,(4f - _stext)@ha  /* Jump to the copy of this code */
 -      addi    r12,r8,(4f - _stext)@l  /* that we just made */
 +      /* Jump to the copy of this code that we just made */
 +      addis   r8,r3,(ABS_ADDR(4f))@ha
 +      addi    r12,r8,(ABS_ADDR(4f))@l
        mtctr   r12
        bctr
  
  .balign 8
 -p_end:        .llong  _end - _stext
 +p_end: .llong _end - copy_to_here
  
 -4:    /* Now copy the rest of the kernel up to _end */
 -      addis   r5,r26,(p_end - _stext)@ha
 -      ld      r5,(p_end - _stext)@l(r5)       /* get _end */
 +4:
 +      /*
 +       * Now copy the rest of the kernel up to _end, add
 +       * _end - copy_to_here to the copy limit and run again.
 +       */
 +      addis   r8,r26,(ABS_ADDR(p_end))@ha
 +      ld      r8,(ABS_ADDR(p_end))@l(r8)
 +      add     r5,r5,r8
  5:    bl      copy_and_flush          /* copy the rest */
  
  9:    b       start_here_multiplatform
@@@ -1002,3 -984,4 +1003,4 @@@ swapper_pg_dir
        .globl  empty_zero_page
  empty_zero_page:
        .space  PAGE_SIZE
+ EXPORT_SYMBOL(empty_zero_page)
@@@ -31,6 -31,7 +31,7 @@@
  #include <asm/asm-offsets.h>
  #include <asm/ptrace.h>
  #include <asm/fixmap.h>
+ #include <asm/export.h>
  
  /* Macro to make the code more readable. */
  #ifdef CONFIG_8xx_CPU6
@@@ -151,6 -152,7 +152,6 @@@ turn_on_mmu
  
  
  #define EXCEPTION_PROLOG_2    \
 -      CLR_TOP32(r11);         \
        stw     r10,_CCR(r11);          /* save registers */ \
        stw     r12,GPR12(r11); \
        stw     r9,GPR9(r11);   \
@@@ -226,7 -228,7 +227,7 @@@ i##n:                                                              
                          ret_from_except)
  
  /* System reset */
 -      EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
 +      EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)
  
  /* Machine check */
        . = 0x200
@@@ -321,7 -323,7 +322,7 @@@ SystemCall
  #endif
  
  InstructionTLBMiss:
 -#ifdef CONFIG_8xx_CPU6
 +#if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
        mtspr   SPRN_SPRG_SCRATCH2, r3
  #endif
        EXCEPTION_PROLOG_0
        /* If we are faulting a kernel address, we have to use the
         * kernel page tables.
         */
 +      mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 +      INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10)
  #if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
        /* Only modules will cause ITLB Misses as we always
         * pin the first 8MB of kernel memory */
 -      mfspr   r11, SPRN_SRR0  /* Get effective address of fault */
 -      INVALIDATE_ADJACENT_PAGES_CPU15(r10, r11)
 -      mfcr    r10
 -      IS_KERNEL(r11, r11)
 +      mfcr    r3
 +      IS_KERNEL(r11, r10)
 +#endif
        mfspr   r11, SPRN_M_TW  /* Get level 1 table */
 +#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
        BRANCH_UNLESS_KERNEL(3f)
        lis     r11, (swapper_pg_dir-PAGE_OFFSET)@ha
  3:
 -      mtcr    r10
 -      mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 -#else
 -      mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 -      INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10)
 -      mfspr   r11, SPRN_M_TW  /* Get level 1 table base address */
 +      mtcr    r3
  #endif
        /* Insert level 1 index */
        rlwimi  r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
        MTSPR_CPU6(SPRN_MI_RPN, r10, r3)        /* Update TLB entry */
  
        /* Restore registers */
 -#ifdef CONFIG_8xx_CPU6
 +#if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
        mfspr   r3, SPRN_SPRG_SCRATCH2
  #endif
        EXCEPTION_EPILOG_0
        rfi
  
 -/*
 - * Bottom part of DataStoreTLBMiss handler for IMMR area
 - * not enough space in the DataStoreTLBMiss area
 - */
 -DTLBMissIMMR:
 -      mtcr    r10
 -      /* Set 512k byte guarded page and mark it valid */
 -      li      r10, MD_PS512K | MD_GUARDED | MD_SVALID
 -      MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
 -      mfspr   r10, SPRN_IMMR                  /* Get current IMMR */
 -      rlwinm  r10, r10, 0, 0xfff80000         /* Get 512 kbytes boundary */
 -      ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
 -                        _PAGE_PRESENT | _PAGE_NO_CACHE
 -      MTSPR_CPU6(SPRN_MD_RPN, r10, r11)       /* Update TLB entry */
 -
 -      li      r11, RPN_PATTERN
 -      mtspr   SPRN_DAR, r11   /* Tag DAR */
 -      EXCEPTION_EPILOG_0
 -      rfi
 -
        . = 0x1200
  DataStoreTLBMiss:
 +      mtspr   SPRN_SPRG_SCRATCH2, r3
        EXCEPTION_PROLOG_0
 -      mfcr    r10
 +      mfcr    r3
  
        /* If we are faulting a kernel address, we have to use the
         * kernel page tables.
         */
 -      mfspr   r11, SPRN_MD_EPN
 -      rlwinm  r11, r11, 16, 0xfff8
 +      mfspr   r10, SPRN_MD_EPN
 +      rlwinm  r10, r10, 16, 0xfff8
 +      cmpli   cr0, r10, PAGE_OFFSET@h
 +      mfspr   r11, SPRN_M_TW  /* Get level 1 table */
 +      blt+    3f
  #ifndef CONFIG_PIN_TLB_IMMR
 -      cmpli   cr0, r11, VIRT_IMMR_BASE@h
 +      cmpli   cr0, r10, VIRT_IMMR_BASE@h
  #endif
 -      cmpli   cr7, r11, PAGE_OFFSET@h
 +_ENTRY(DTLBMiss_cmp)
 +      cmpli   cr7, r10, (PAGE_OFFSET + 0x1800000)@h
 +      lis     r11, (swapper_pg_dir-PAGE_OFFSET)@ha
  #ifndef CONFIG_PIN_TLB_IMMR
  _ENTRY(DTLBMiss_jmp)
        beq-    DTLBMissIMMR
  #endif
 -      bge-    cr7, 4f
 -
 -      mfspr   r11, SPRN_M_TW  /* Get level 1 table */
 +      blt     cr7, DTLBMissLinear
  3:
 -      mtcr    r10
 -#ifdef CONFIG_8xx_CPU6
 -      mtspr   SPRN_SPRG_SCRATCH2, r3
 -#endif
 +      mtcr    r3
        mfspr   r10, SPRN_MD_EPN
  
        /* Insert level 1 index */
        MTSPR_CPU6(SPRN_MD_RPN, r10, r3)        /* Update TLB entry */
  
        /* Restore registers */
 -#ifdef CONFIG_8xx_CPU6
        mfspr   r3, SPRN_SPRG_SCRATCH2
 -#endif
 -      mtspr   SPRN_DAR, r11   /* Tag DAR */
 -      EXCEPTION_EPILOG_0
 -      rfi
 -
 -4:
 -_ENTRY(DTLBMiss_cmp)
 -      cmpli   cr0, r11, (PAGE_OFFSET + 0x1800000)@h
 -      lis     r11, (swapper_pg_dir-PAGE_OFFSET)@ha
 -      bge-    3b
 -
 -      mtcr    r10
 -      /* Set 8M byte page and mark it valid */
 -      li      r10, MD_PS8MEG | MD_SVALID
 -      MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
 -      mfspr   r10, SPRN_MD_EPN
 -      rlwinm  r10, r10, 0, 0x0f800000         /* 8xx supports max 256Mb RAM */
 -      ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
 -                        _PAGE_PRESENT
 -      MTSPR_CPU6(SPRN_MD_RPN, r10, r11)       /* Update TLB entry */
 -
 -      li      r11, RPN_PATTERN
        mtspr   SPRN_DAR, r11   /* Tag DAR */
        EXCEPTION_EPILOG_0
        rfi
@@@ -525,43 -572,6 +526,43 @@@ DARFixed:/* Return from dcbx instructio
  
        . = 0x2000
  
 +/*
 + * Bottom part of DataStoreTLBMiss handlers for IMMR area and linear RAM.
 + * not enough space in the DataStoreTLBMiss area.
 + */
 +DTLBMissIMMR:
 +      mtcr    r3
 +      /* Set 512k byte guarded page and mark it valid */
 +      li      r10, MD_PS512K | MD_GUARDED | MD_SVALID
 +      MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
 +      mfspr   r10, SPRN_IMMR                  /* Get current IMMR */
 +      rlwinm  r10, r10, 0, 0xfff80000         /* Get 512 kbytes boundary */
 +      ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
 +                        _PAGE_PRESENT | _PAGE_NO_CACHE
 +      MTSPR_CPU6(SPRN_MD_RPN, r10, r11)       /* Update TLB entry */
 +
 +      li      r11, RPN_PATTERN
 +      mtspr   SPRN_DAR, r11   /* Tag DAR */
 +      mfspr   r3, SPRN_SPRG_SCRATCH2
 +      EXCEPTION_EPILOG_0
 +      rfi
 +
 +DTLBMissLinear:
 +      mtcr    r3
 +      /* Set 8M byte page and mark it valid */
 +      li      r11, MD_PS8MEG | MD_SVALID
 +      MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
 +      rlwinm  r10, r10, 16, 0x0f800000        /* 8xx supports max 256Mb RAM */
 +      ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
 +                        _PAGE_PRESENT
 +      MTSPR_CPU6(SPRN_MD_RPN, r10, r11)       /* Update TLB entry */
 +
 +      li      r11, RPN_PATTERN
 +      mtspr   SPRN_DAR, r11   /* Tag DAR */
 +      mfspr   r3, SPRN_SPRG_SCRATCH2
 +      EXCEPTION_EPILOG_0
 +      rfi
 +
  /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
   * by decoding the registers used by the dcbx instruction and adding them.
   * DAR is set to the calculated address.
@@@ -578,9 -588,7 +579,9 @@@ FixupDAR:/* Entry point for dcbx workar
        rlwinm  r11, r10, 16, 0xfff8
  _ENTRY(FixupDAR_cmp)
        cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
 -      blt-    cr7, 200f
 +      /* create physical page address from effective address */
 +      tophys(r11, r10)
 +      blt-    cr7, 201f
        lis     r11, (swapper_pg_dir-PAGE_OFFSET)@ha
        /* Insert level 1 index */
  3:    rlwimi  r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
  141:  mfspr   r10,SPRN_SPRG_SCRATCH2
        b       DARFixed        /* Nope, go back to normal TLB processing */
  
 -      /* create physical page address from effective address */
 -200:  tophys(r11, r10)
 -      b       201b
 -
  144:  mfspr   r10, SPRN_DSISR
        rlwinm  r10, r10,0,7,5  /* Clear store bit for buggy dcbst insn */
        mtspr   SPRN_DSISR, r10
@@@ -884,6 -896,7 +885,7 @@@ sdata
        .align  PAGE_SHIFT
  empty_zero_page:
        .space  PAGE_SIZE
+ EXPORT_SYMBOL(empty_zero_page)
  
        .globl  swapper_pg_dir
  swapper_pg_dir:
@@@ -33,6 -33,7 +33,7 @@@
  #include <asm/kexec.h>
  #include <asm/bug.h>
  #include <asm/ptrace.h>
+ #include <asm/export.h>
  
        .text
  
@@@ -319,6 -320,7 +320,7 @@@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_I
  #endif /* CONFIG_4xx */
        isync
        blr
+ EXPORT_SYMBOL(flush_instruction_cache)
  #endif /* CONFIG_PPC_8xx */
  
  /*
   *
   * flush_icache_range(unsigned long start, unsigned long stop)
   */
 -_KPROBE(flush_icache_range)
 +_GLOBAL(flush_icache_range)
  BEGIN_FTR_SECTION
        PURGE_PREFETCHED_INS
        blr                             /* for 601, do nothing */
@@@ -358,8 -360,7 +360,9 @@@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_
        sync                            /* additional sync needed on g4 */
        isync
        blr
 +_ASM_NOKPROBE_SYMBOL(flush_icache_range)
+ EXPORT_SYMBOL(flush_icache_range)
 +
  /*
   * Flush a particular page from the data cache to RAM.
   * Note: this is necessary because the instruction cache does *not*
@@@ -497,6 -498,7 +500,7 @@@ _GLOBAL(copy_page
        li      r0,MAX_COPY_PREFETCH
        li      r11,4
        b       2b
+ EXPORT_SYMBOL(copy_page)
  
  /*
   * Extended precision shifts.
@@@ -524,6 -526,7 +528,7 @@@ _GLOBAL(__ashrdi3
        sraw    r3,r3,r5        # MSW = MSW >> count
        or      r4,r4,r7        # LSW |= t2
        blr
+ EXPORT_SYMBOL(__ashrdi3)
  
  _GLOBAL(__ashldi3)
        subfic  r6,r5,32
        slw     r4,r4,r5        # LSW = LSW << count
        or      r3,r3,r7        # MSW |= t2
        blr
+ EXPORT_SYMBOL(__ashldi3)
  
  _GLOBAL(__lshrdi3)
        subfic  r6,r5,32
        srw     r3,r3,r5        # MSW = MSW >> count
        or      r4,r4,r7        # LSW |= t2
        blr
+ EXPORT_SYMBOL(__lshrdi3)
  
  /*
   * 64-bit comparison: __cmpdi2(s64 a, s64 b)
@@@ -561,6 -566,7 +568,7 @@@ _GLOBAL(__cmpdi2
        bltlr
        li      r3,2
        blr
+ EXPORT_SYMBOL(__cmpdi2)
  /*
   * 64-bit comparison: __ucmpdi2(u64 a, u64 b)
   * Returns 0 if a < b, 1 if a == b, 2 if a > b.
@@@ -575,6 -581,7 +583,7 @@@ _GLOBAL(__ucmpdi2
        bltlr
        li      r3,2
        blr
+ EXPORT_SYMBOL(__ucmpdi2)
  
  _GLOBAL(__bswapdi2)
        rotlwi  r9,r4,8
        mr      r3,r9
        mr      r4,r10
        blr
+ EXPORT_SYMBOL(__bswapdi2)
  
  #ifdef CONFIG_SMP
  _GLOBAL(start_secondary_resume)
@@@ -27,6 -27,7 +27,7 @@@
  #include <asm/kexec.h>
  #include <asm/ptrace.h>
  #include <asm/mmu.h>
+ #include <asm/export.h>
  
        .text
  
@@@ -66,7 -67,7 +67,7 @@@ PPC64_CACHES
   *   flush all bytes from start through stop-1 inclusive
   */
  
 -_KPROBE(flush_icache_range)
 +_GLOBAL(flush_icache_range)
  BEGIN_FTR_SECTION
        PURGE_PREFETCHED_INS
        blr
@@@ -109,8 -110,8 +110,9 @@@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_
        bdnz    2b
        isync
        blr
 -      .previous .text
 +_ASM_NOKPROBE_SYMBOL(flush_icache_range)
+ EXPORT_SYMBOL(flush_icache_range)
 +
  /*
   * Like above, but only do the D-cache.
   *
@@@ -140,6 -141,7 +142,7 @@@ _GLOBAL(flush_dcache_range
        bdnz    0b
        sync
        blr
+ EXPORT_SYMBOL(flush_dcache_range)
  
  /*
   * Like above, but works on non-mapped physical addresses.
@@@ -243,6 -245,7 +246,7 @@@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_
        blr
  
  _GLOBAL(__bswapdi2)
+ EXPORT_SYMBOL(__bswapdi2)
        srdi    r8,r3,32
        rlwinm  r7,r3,8,0xffffffff
        rlwimi  r7,r3,24,0,7
@@@ -592,8 -595,7 +596,8 @@@ real_mode: /* assume normal blr return 
  #endif
  
  /*
 - * kexec_sequence(newstack, start, image, control, clear_all())
 + * kexec_sequence(newstack, start, image, control, clear_all(),
 +                copy_with_mmu_off)
   *
   * does the grungy work with stack switching and real mode switches
   * also does simple calls to other code
@@@ -629,7 -631,7 +633,7 @@@ _GLOBAL(kexec_sequence
        mr      r29,r5                  /* image (virt) */
        mr      r28,r6                  /* control, unused */
        mr      r27,r7                  /* clear_all() fn desc */
 -      mr      r26,r8                  /* spare */
 +      mr      r26,r8                  /* copy_with_mmu_off */
        lhz     r25,PACAHWCPUID(r13)    /* get our phys cpu from paca */
  
        /* disable interrupts, we are overwriting kernel data next */
        mtmsrd  r3,1
  #endif
  
 +      /* We need to turn the MMU off unless we are in hash mode
 +       * under a hypervisor
 +       */
 +      cmpdi   r26,0
 +      beq     1f
 +      bl      real_mode
 +1:
        /* copy dest pages, flush whole dest image */
        mr      r3,r29
        bl      kexec_copy_flush        /* (image) */
  
 -      /* turn off mmu */
 +      /* turn off mmu now if not done earlier */
 +      cmpdi   r26,0
 +      bne     1f
        bl      real_mode
  
        /* copy  0x100 bytes starting at start to 0 */
 -      li      r3,0
 +1:    li      r3,0
        mr      r4,r30          /* start, aka phys mem offset */
        li      r5,0x100
        li      r6,0
        li      r6,1
        stw     r6,kexec_flag-1b(5)
  
 -#ifndef CONFIG_PPC_BOOK3E
 +      cmpdi   r27,0
 +      beq     1f
 +
        /* clear out hardware hash page table and tlb */
  #ifdef PPC64_ELF_ABI_v1
        ld      r12,0(r27)              /* deref function descriptor */
  #endif
        mtctr   r12
        bctrl                           /* mmu_hash_ops.hpte_clear_all(void); */
 -#endif /* !CONFIG_PPC_BOOK3E */
  
  /*
   *   kexec image calling is:
   *    are the boot cpu ?????
   *    other device tree differences (prop sizes, va vs pa, etc)...
   */
 -      mr      r3,r25  # my phys cpu
 +1:    mr      r3,r25  # my phys cpu
        mr      r4,r30  # start, aka phys mem offset
        mtlr    4
        li      r5,0
@@@ -56,6 -56,7 +56,7 @@@ static DECLARE_BITMAP(phb_bitmap, MAX_P
  
  /* ISA Memory physical address */
  resource_size_t isa_mem_base;
+ EXPORT_SYMBOL(isa_mem_base);
  
  
  static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
@@@ -78,7 -79,6 +79,7 @@@ EXPORT_SYMBOL(get_pci_dma_ops)
  static int get_phb_number(struct device_node *dn)
  {
        int ret, phb_id = -1;
 +      u32 prop_32;
        u64 prop;
  
        /*
         * reading "ibm,opal-phbid", only present in OPAL environment.
         */
        ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop);
 -      if (ret)
 -              ret = of_property_read_u32_index(dn, "reg", 1, (u32 *)&prop);
 +      if (ret) {
 +              ret = of_property_read_u32_index(dn, "reg", 1, &prop_32);
 +              prop = prop_32;
 +      }
  
        if (!ret)
                phb_id = (int)(prop & (MAX_PHBS - 1));
@@@ -153,42 -151,6 +154,42 @@@ void pcibios_free_controller(struct pci
  }
  EXPORT_SYMBOL_GPL(pcibios_free_controller);
  
 +/*
 + * This function is used to call pcibios_free_controller()
 + * in a deferred manner: a callback from the PCI subsystem.
 + *
 + * _*DO NOT*_ call pcibios_free_controller() explicitly if
 + * this is used (or it may access an invalid *phb pointer).
 + *
 + * The callback occurs when all references to the root bus
 + * are dropped (e.g., child buses/devices and their users).
 + *
 + * It's called as .release_fn() of 'struct pci_host_bridge'
 + * which is associated with the 'struct pci_controller.bus'
 + * (root bus) - it expects .release_data to hold a pointer
 + * to 'struct pci_controller'.
 + *
 + * In order to use it, register .release_fn()/release_data
 + * like this:
 + *
 + * pci_set_host_bridge_release(bridge,
 + *                             pcibios_free_controller_deferred
 + *                             (void *) phb);
 + *
 + * e.g. in the pcibios_root_bridge_prepare() callback from
 + * pci_create_root_bus().
 + */
 +void pcibios_free_controller_deferred(struct pci_host_bridge *bridge)
 +{
 +      struct pci_controller *phb = (struct pci_controller *)
 +                                       bridge->release_data;
 +
 +      pr_debug("domain %d, dynamic %d\n", phb->global_number, phb->is_dynamic);
 +
 +      pcibios_free_controller(phb);
 +}
 +EXPORT_SYMBOL_GPL(pcibios_free_controller_deferred);
 +
  /*
   * The function is used to return the minimal alignment
   * for memory or I/O windows of the associated P2P bridge.
@@@ -360,7 -322,7 +361,7 @@@ static int pci_read_irq_line(struct pci
                         line, pin);
  
                virq = irq_create_mapping(NULL, line);
 -              if (virq != NO_IRQ)
 +              if (virq)
                        irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
        } else {
                pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
  
                virq = irq_create_of_mapping(&oirq);
        }
 -      if(virq == NO_IRQ) {
 +
 +      if (!virq) {
                pr_debug(" Failed to map !\n");
                return -1;
        }
@@@ -16,6 -16,7 +16,7 @@@
  #include <linux/cpu.h>
  #include <linux/console.h>
  #include <linux/memblock.h>
+ #include <linux/export.h>
  
  #include <asm/io.h>
  #include <asm/prom.h>
@@@ -47,11 -48,16 +48,16 @@@ int boot_cpuid_phys
  EXPORT_SYMBOL_GPL(boot_cpuid_phys);
  
  int smp_hw_index[NR_CPUS];
+ EXPORT_SYMBOL(smp_hw_index);
  
  unsigned long ISA_DMA_THRESHOLD;
  unsigned int DMA_MODE_READ;
  unsigned int DMA_MODE_WRITE;
  
+ EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
+ EXPORT_SYMBOL(DMA_MODE_READ);
+ EXPORT_SYMBOL(DMA_MODE_WRITE);
  /*
   * These are used in binfmt_elf.c to put aux entries on the stack
   * for each elf executable being started.
@@@ -93,16 -99,15 +99,16 @@@ notrace unsigned long __init early_init
   * and we are running with enough of the MMU enabled to have our
   * proper kernel virtual addresses
   *
 - * Find out what kind of machine we're on and save any data we need
 - * from the early boot process (devtree is copied on pmac by prom_init()).
 - * This is called very early on the boot process, after a minimal
 - * MMU environment has been set up but before MMU_init is called.
 + * We do the initial parsing of the flat device-tree and prepares
 + * for the MMU to be fully initialized.
   */
  extern unsigned int memset_nocache_branch; /* Insn to be replaced by NOP */
  
  notrace void __init machine_init(u64 dt_ptr)
  {
 +      /* Configure static keys first, now that we're relocated. */
 +      setup_feature_keys();
 +
        /* Enable early debugging if any specified (see udbg.h) */
        udbg_early_init();
  
@@@ -73,7 -73,6 +73,7 @@@
  #include <asm/vdso_datapage.h>
  #include <asm/firmware.h>
  #include <asm/cputime.h>
 +#include <asm/asm-prototypes.h>
  
  /* powerpc clocksource/clockevent code */
  
@@@ -596,6 -595,7 +596,7 @@@ void timer_interrupt(struct pt_regs * r
        irq_exit();
        set_irq_regs(old_regs);
  }
+ EXPORT_SYMBOL(timer_interrupt);
  
  /*
   * Hypervisor decrementer interrupts shouldn't occur but are sometimes
@@@ -6,7 -6,33 +6,8 @@@
  #include <asm/thread_info.h>
  #include <asm/page.h>
  #include <asm/ptrace.h>
+ #include <asm/export.h>
  
 -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 -/* void do_load_up_transact_altivec(struct thread_struct *thread)
 - *
 - * This is similar to load_up_altivec but for the transactional version of the
 - * vector regs.  It doesn't mess with the task MSR or valid flags.
 - * Furthermore, VEC laziness is not supported with TM currently.
 - */
 -_GLOBAL(do_load_up_transact_altivec)
 -      mfmsr   r6
 -      oris    r5,r6,MSR_VEC@h
 -      MTMSRD(r5)
 -      isync
 -
 -      li      r4,1
 -      stw     r4,THREAD_USED_VR(r3)
 -
 -      li      r10,THREAD_TRANSACT_VRSTATE+VRSTATE_VSCR
 -      lvx     v0,r10,r3
 -      mtvscr  v0
 -      addi    r10,r3,THREAD_TRANSACT_VRSTATE
 -      REST_32VRS(0,r4,r10)
 -
 -      blr
 -#endif
 -
  /*
   * Load state from memory into VMX registers including VSCR.
   * Assumes the caller has enabled VMX in the MSR.
@@@ -17,6 -43,7 +18,7 @@@ _GLOBAL(load_vr_state
        mtvscr  v0
        REST_32VRS(0,r4,r3)
        blr
+ EXPORT_SYMBOL(load_vr_state)
  
  /*
   * Store VMX state into memory, including VSCR.
@@@ -28,6 -55,7 +30,7 @@@ _GLOBAL(store_vr_state
        li      r4, VRSTATE_VSCR
        stvx    v0, r4, r3
        blr
+ EXPORT_SYMBOL(store_vr_state)
  
  /*
   * Disable VMX for the task which had it previously,
@@@ -9,7 -9,7 +9,7 @@@ ccflags-$(CONFIG_PPC64)  := $(NO_MINIMAL
  CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
  CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
  
- obj-y += string.o alloc.o crtsavres.o ppc_ksyms.o code-patching.o \
+ obj-y += string.o alloc.o crtsavres.o code-patching.o \
         feature-fixups.o
  
  obj-$(CONFIG_PPC32)   += div64.o copy_32.o
@@@ -22,7 -22,7 +22,7 @@@ obj64-$(CONFIG_SMP)   += locks.
  obj64-$(CONFIG_ALTIVEC)       += vmx-helper.o
  
  ifeq ($(CONFIG_GENERIC_CSUM),)
 -obj-y                 += checksum_$(CONFIG_WORD_SIZE).o checksum_wrappers.o
 +obj-y                 += checksum_$(BITS).o checksum_wrappers.o
  endif
  
  obj-$(CONFIG_PPC_EMULATE_SSTEP)       += sstep.o ldstfp.o
@@@ -17,6 -17,7 +17,7 @@@
  #include <asm/cache.h>
  #include <asm/errno.h>
  #include <asm/ppc_asm.h>
+ #include <asm/export.h>
  
        .text
  
@@@ -68,6 -69,7 +69,7 @@@ _GLOBAL(__csum_partial
        adde    r5,r5,r0
  5:    addze   r3,r5           /* add in final carry */
        blr
+ EXPORT_SYMBOL(__csum_partial)
  
  /*
   * Computes the checksum of a memory block at src, length len,
@@@ -127,19 -129,17 +129,19 @@@ _GLOBAL(csum_partial_copy_generic
        stw     r7,12(r1)
        stw     r8,8(r1)
  
 -      andi.   r0,r4,1                 /* is destination address even ? */
 -      cmplwi  cr7,r0,0
        addic   r12,r6,0
        addi    r6,r4,-4
        neg     r0,r4
        addi    r4,r3,-4
        andi.   r0,r0,CACHELINE_MASK    /* # bytes to start of cache line */
 +      crset   4*cr7+eq
        beq     58f
  
        cmplw   0,r5,r0                 /* is this more than total to do? */
        blt     63f                     /* if not much to do */
 +      rlwinm  r7,r6,3,0x8
 +      rlwnm   r12,r12,r7,0,31 /* odd destination address: rotate one byte */
 +      cmplwi  cr7,r7,0        /* is destination address even ? */
        andi.   r8,r0,3                 /* get it word-aligned first */
        mtctr   r8
        beq+    61f
  66:   addze   r3,r12
        addi    r1,r1,16
        beqlr+  cr7
 -      rlwinm  r3,r3,8,0,31    /* swap bytes for odd destination */
 +      rlwinm  r3,r3,8,0,31    /* odd destination address: rotate one byte */
        blr
  
  /* read fault */
@@@ -297,3 -297,4 +299,4 @@@ dst_error
        .long   41b,dst_error
        .long   50b,src_error
        .long   51b,dst_error
+ EXPORT_SYMBOL(csum_partial_copy_generic)
@@@ -8,6 -8,7 +8,7 @@@
   */
  #include <asm/processor.h>
  #include <asm/ppc_asm.h>
+ #include <asm/export.h>
  
  #ifdef __BIG_ENDIAN__
  #define sLd sld               /* Shift towards low-numbered address. */
@@@ -359,7 -360,6 +360,7 @@@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED
        addi    r3,r3,8
  171:
  177:
 +179:
        addi    r3,r3,8
  370:
  372:
  173:
  174:
  175:
 -179:
  181:
  184:
  186:
        .llong  89b,100b
        .llong  90b,100b
        .llong  91b,100b
+ EXPORT_SYMBOL(__copy_tofrom_user)
@@@ -11,6 -11,7 +11,7 @@@
  #include <asm/processor.h>
  #include <asm/errno.h>
  #include <asm/ppc_asm.h>
+ #include <asm/export.h>
  
  _GLOBAL(memset)
        neg     r0,r3
@@@ -37,7 -38,6 +38,7 @@@
        clrldi  r5,r5,58
        mtctr   r0
        beq     5f
 +      .balign 16
  4:    std     r4,0(r6)
        std     r4,8(r6)
        std     r4,16(r6)
@@@ -77,6 -77,7 +78,7 @@@
  10:   bflr    31
        stb     r4,0(r6)
        blr
+ EXPORT_SYMBOL(memset)
  
  _GLOBAL_TOC(memmove)
        cmplw   0,r3,r4
@@@ -91,7 -92,6 +93,7 @@@ _GLOBAL(backwards_memcpy
        andi.   r0,r6,3
        mtctr   r7
        bne     5f
 +      .balign 16
  1:    lwz     r7,-4(r4)
        lwzu    r8,-8(r4)
        stw     r7,-4(r6)
        beq     2b
        mtctr   r7
        b       1b
+ EXPORT_SYMBOL(memmove)
@@@ -48,9 -48,6 +48,9 @@@ AFLAGS_head.o         += -march=z90
  endif
  GCOV_PROFILE_sclp.o := n
  GCOV_PROFILE_als.o := n
 +UBSAN_SANITIZE_als.o := n
 +UBSAN_SANITIZE_early.o := n
 +UBSAN_SANITIZE_sclp.o := n
  
  obj-y := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o
  obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
@@@ -61,7 -58,7 +61,7 @@@ obj-y += entry.o reipl.o relocate_kerne
  
  extra-y                               += head.o head64.o vmlinux.lds
  
- obj-$(CONFIG_MODULES)         += s390_ksyms.o module.o
+ obj-$(CONFIG_MODULES)         += module.o
  obj-$(CONFIG_SMP)             += smp.o
  obj-$(CONFIG_SCHED_TOPOLOGY)  += topology.o
  obj-$(CONFIG_HIBERNATION)     += suspend.o swsusp.o
@@@ -44,6 -44,7 +44,7 @@@
  #include <asm/alternative-asm.h>
  #include <asm/asm.h>
  #include <asm/smap.h>
+ #include <asm/export.h>
  
        .section .entry.text, "ax"
  
        POP_GS_EX
  .endm
  
 +/*
 + * %eax: prev task
 + * %edx: next task
 + */
 +ENTRY(__switch_to_asm)
 +      /*
 +       * Save callee-saved registers
 +       * This must match the order in struct inactive_task_frame
 +       */
 +      pushl   %ebp
 +      pushl   %ebx
 +      pushl   %edi
 +      pushl   %esi
 +
 +      /* switch stack */
 +      movl    %esp, TASK_threadsp(%eax)
 +      movl    TASK_threadsp(%edx), %esp
 +
 +#ifdef CONFIG_CC_STACKPROTECTOR
 +      movl    TASK_stack_canary(%edx), %ebx
 +      movl    %ebx, PER_CPU_VAR(stack_canary)+stack_canary_offset
 +#endif
 +
 +      /* restore callee-saved registers */
 +      popl    %esi
 +      popl    %edi
 +      popl    %ebx
 +      popl    %ebp
 +
 +      jmp     __switch_to
 +END(__switch_to_asm)
 +
 +/*
 + * A newly forked process directly context switches into this address.
 + *
 + * eax: prev task we switched from
 + * ebx: kernel thread func (NULL for user thread)
 + * edi: kernel thread arg
 + */
  ENTRY(ret_from_fork)
        pushl   %eax
        call    schedule_tail
        popl    %eax
  
 +      testl   %ebx, %ebx
 +      jnz     1f              /* kernel threads are uncommon */
 +
 +2:
        /* When we fork, we trace the syscall return in the child, too. */
        movl    %esp, %eax
        call    syscall_return_slowpath
        jmp     restore_all
 -END(ret_from_fork)
 -
 -ENTRY(ret_from_kernel_thread)
 -      pushl   %eax
 -      call    schedule_tail
 -      popl    %eax
 -      movl    PT_EBP(%esp), %eax
 -      call    *PT_EBX(%esp)
 -      movl    $0, PT_EAX(%esp)
  
 +      /* kernel thread */
 +1:    movl    %edi, %eax
 +      call    *%ebx
        /*
 -       * Kernel threads return to userspace as if returning from a syscall.
 -       * We should check whether anything actually uses this path and, if so,
 -       * consider switching it over to ret_from_fork.
 +       * A kernel thread is allowed to return here after successfully
 +       * calling do_execve().  Exit to userspace to complete the execve()
 +       * syscall.
         */
 -      movl    %esp, %eax
 -      call    syscall_return_slowpath
 -      jmp     restore_all
 -ENDPROC(ret_from_kernel_thread)
 +      movl    $0, PT_EAX(%esp)
 +      jmp     2b
 +END(ret_from_fork)
  
  /*
   * Return to user mode is not as complex as all this looks,
@@@ -991,6 -956,7 +992,7 @@@ trace
        jmp     ftrace_stub
  END(mcount)
  #endif /* CONFIG_DYNAMIC_FTRACE */
+ EXPORT_SYMBOL(mcount)
  #endif /* CONFIG_FUNCTION_TRACER */
  
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@@ -35,6 -35,7 +35,7 @@@
  #include <asm/asm.h>
  #include <asm/smap.h>
  #include <asm/pgtable_types.h>
+ #include <asm/export.h>
  #include <linux/err.h>
  
  /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
@@@ -179,8 -180,7 +180,8 @@@ GLOBAL(entry_SYSCALL_64_after_swapgs
         * If we need to do entry work or if we guess we'll need to do
         * exit work, go straight to the slow path.
         */
 -      testl   $_TIF_WORK_SYSCALL_ENTRY|_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
 +      movq    PER_CPU_VAR(current_task), %r11
 +      testl   $_TIF_WORK_SYSCALL_ENTRY|_TIF_ALLWORK_MASK, TASK_TI_flags(%r11)
        jnz     entry_SYSCALL64_slow_path
  
  entry_SYSCALL_64_fastpath:
         */
        DISABLE_INTERRUPTS(CLBR_NONE)
        TRACE_IRQS_OFF
 -      testl   $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
 +      movq    PER_CPU_VAR(current_task), %r11
 +      testl   $_TIF_ALLWORK_MASK, TASK_TI_flags(%r11)
        jnz     1f
  
        LOCKDEP_SYS_EXIT
@@@ -290,15 -289,11 +291,15 @@@ return_from_SYSCALL_64
        jne     opportunistic_sysret_failed
  
        /*
 -       * SYSRET can't restore RF.  SYSRET can restore TF, but unlike IRET,
 -       * restoring TF results in a trap from userspace immediately after
 -       * SYSRET.  This would cause an infinite loop whenever #DB happens
 -       * with register state that satisfies the opportunistic SYSRET
 -       * conditions.  For example, single-stepping this user code:
 +       * SYSCALL clears RF when it saves RFLAGS in R11 and SYSRET cannot
 +       * restore RF properly. If the slowpath sets it for whatever reason, we
 +       * need to restore it correctly.
 +       *
 +       * SYSRET can restore TF, but unlike IRET, restoring TF results in a
 +       * trap from userspace immediately after SYSRET.  This would cause an
 +       * infinite loop whenever #DB happens with register state that satisfies
 +       * the opportunistic SYSRET conditions.  For example, single-stepping
 +       * this user code:
         *
         *           movq       $stuck_here, %rcx
         *           pushfq
@@@ -353,7 -348,8 +354,7 @@@ ENTRY(stub_ptregs_64
        jmp     entry_SYSCALL64_slow_path
  
  1:
 -      /* Called from C */
 -      jmp     *%rax                           /* called from C */
 +      jmp     *%rax                           /* Called from C */
  END(stub_ptregs_64)
  
  .macro ptregs_stub func
@@@ -369,74 -365,42 +370,74 @@@ END(ptregs_\func
  #define __SYSCALL_64(nr, sym, qual) __SYSCALL_64_QUAL_##qual(sym)
  #include <asm/syscalls_64.h>
  
 +/*
 + * %rdi: prev task
 + * %rsi: next task
 + */
 +ENTRY(__switch_to_asm)
 +      /*
 +       * Save callee-saved registers
 +       * This must match the order in inactive_task_frame
 +       */
 +      pushq   %rbp
 +      pushq   %rbx
 +      pushq   %r12
 +      pushq   %r13
 +      pushq   %r14
 +      pushq   %r15
 +
 +      /* switch stack */
 +      movq    %rsp, TASK_threadsp(%rdi)
 +      movq    TASK_threadsp(%rsi), %rsp
 +
 +#ifdef CONFIG_CC_STACKPROTECTOR
 +      movq    TASK_stack_canary(%rsi), %rbx
 +      movq    %rbx, PER_CPU_VAR(irq_stack_union)+stack_canary_offset
 +#endif
 +
 +      /* restore callee-saved registers */
 +      popq    %r15
 +      popq    %r14
 +      popq    %r13
 +      popq    %r12
 +      popq    %rbx
 +      popq    %rbp
 +
 +      jmp     __switch_to
 +END(__switch_to_asm)
 +
  /*
   * A newly forked process directly context switches into this address.
   *
 - * rdi: prev task we switched from
 + * rax: prev task we switched from
 + * rbx: kernel thread func (NULL for user thread)
 + * r12: kernel thread arg
   */
  ENTRY(ret_from_fork)
 -      LOCK ; btr $TIF_FORK, TI_flags(%r8)
 -
 +      movq    %rax, %rdi
        call    schedule_tail                   /* rdi: 'prev' task parameter */
  
 -      testb   $3, CS(%rsp)                    /* from kernel_thread? */
 -      jnz     1f
 -
 -      /*
 -       * We came from kernel_thread.  This code path is quite twisted, and
 -       * someone should clean it up.
 -       *
 -       * copy_thread_tls stashes the function pointer in RBX and the
 -       * parameter to be passed in RBP.  The called function is permitted
 -       * to call do_execve and thereby jump to user mode.
 -       */
 -      movq    RBP(%rsp), %rdi
 -      call    *RBX(%rsp)
 -      movl    $0, RAX(%rsp)
 -
 -      /*
 -       * Fall through as though we're exiting a syscall.  This makes a
 -       * twisted sort of sense if we just called do_execve.
 -       */
 +      testq   %rbx, %rbx                      /* from kernel_thread? */
 +      jnz     1f                              /* kernel threads are uncommon */
  
 -1:
 +2:
        movq    %rsp, %rdi
        call    syscall_return_slowpath /* returns with IRQs disabled */
        TRACE_IRQS_ON                   /* user mode is traced as IRQS on */
        SWAPGS
        jmp     restore_regs_and_iret
 +
 +1:
 +      /* kernel thread */
 +      movq    %r12, %rdi
 +      call    *%rbx
 +      /*
 +       * A kernel thread is allowed to return here after successfully
 +       * calling do_execve().  Exit to userspace to complete the execve()
 +       * syscall.
 +       */
 +      movq    $0, RAX(%rsp)
 +      jmp     2b
  END(ret_from_fork)
  
  /*
@@@ -588,69 -552,27 +589,69 @@@ native_irq_return_iret
  
  #ifdef CONFIG_X86_ESPFIX64
  native_irq_return_ldt:
 -      pushq   %rax
 -      pushq   %rdi
 +      /*
 +       * We are running with user GSBASE.  All GPRs contain their user
 +       * values.  We have a percpu ESPFIX stack that is eight slots
 +       * long (see ESPFIX_STACK_SIZE).  espfix_waddr points to the bottom
 +       * of the ESPFIX stack.
 +       *
 +       * We clobber RAX and RDI in this code.  We stash RDI on the
 +       * normal stack and RAX on the ESPFIX stack.
 +       *
 +       * The ESPFIX stack layout we set up looks like this:
 +       *
 +       * --- top of ESPFIX stack ---
 +       * SS
 +       * RSP
 +       * RFLAGS
 +       * CS
 +       * RIP  <-- RSP points here when we're done
 +       * RAX  <-- espfix_waddr points here
 +       * --- bottom of ESPFIX stack ---
 +       */
 +
 +      pushq   %rdi                            /* Stash user RDI */
        SWAPGS
        movq    PER_CPU_VAR(espfix_waddr), %rdi
 -      movq    %rax, (0*8)(%rdi)               /* RAX */
 -      movq    (2*8)(%rsp), %rax               /* RIP */
 +      movq    %rax, (0*8)(%rdi)               /* user RAX */
 +      movq    (1*8)(%rsp), %rax               /* user RIP */
        movq    %rax, (1*8)(%rdi)
 -      movq    (3*8)(%rsp), %rax               /* CS */
 +      movq    (2*8)(%rsp), %rax               /* user CS */
        movq    %rax, (2*8)(%rdi)
 -      movq    (4*8)(%rsp), %rax               /* RFLAGS */
 +      movq    (3*8)(%rsp), %rax               /* user RFLAGS */
        movq    %rax, (3*8)(%rdi)
 -      movq    (6*8)(%rsp), %rax               /* SS */
 +      movq    (5*8)(%rsp), %rax               /* user SS */
        movq    %rax, (5*8)(%rdi)
 -      movq    (5*8)(%rsp), %rax               /* RSP */
 +      movq    (4*8)(%rsp), %rax               /* user RSP */
        movq    %rax, (4*8)(%rdi)
 -      andl    $0xffff0000, %eax
 -      popq    %rdi
 +      /* Now RAX == RSP. */
 +
 +      andl    $0xffff0000, %eax               /* RAX = (RSP & 0xffff0000) */
 +      popq    %rdi                            /* Restore user RDI */
 +
 +      /*
 +       * espfix_stack[31:16] == 0.  The page tables are set up such that
 +       * (espfix_stack | (X & 0xffff0000)) points to a read-only alias of
 +       * espfix_waddr for any X.  That is, there are 65536 RO aliases of
 +       * the same page.  Set up RSP so that RSP[31:16] contains the
 +       * respective 16 bits of the /userspace/ RSP and RSP nonetheless
 +       * still points to an RO alias of the ESPFIX stack.
 +       */
        orq     PER_CPU_VAR(espfix_stack), %rax
        SWAPGS
        movq    %rax, %rsp
 -      popq    %rax
 +
 +      /*
 +       * At this point, we cannot write to the stack any more, but we can
 +       * still read.
 +       */
 +      popq    %rax                            /* Restore user RAX */
 +
 +      /*
 +       * RSP now points to an ordinary IRET frame, except that the page
 +       * is read-only and RSP[31:16] are preloaded with the userspace
 +       * values.  We can now IRET back to userspace.
 +       */
        jmp     native_irq_return_iret
  #endif
  END(common_interrupt)
@@@ -680,20 -602,9 +681,20 @@@ apicinterrupt3 \num trace(\sym) smp_tra
  .endm
  #endif
  
 +/* Make sure APIC interrupt handlers end up in the irqentry section: */
 +#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN)
 +# define PUSH_SECTION_IRQENTRY        .pushsection .irqentry.text, "ax"
 +# define POP_SECTION_IRQENTRY .popsection
 +#else
 +# define PUSH_SECTION_IRQENTRY
 +# define POP_SECTION_IRQENTRY
 +#endif
 +
  .macro apicinterrupt num sym do_sym
 +PUSH_SECTION_IRQENTRY
  apicinterrupt3 \num \sym \do_sym
  trace_apicinterrupt \num \sym
 +POP_SECTION_IRQENTRY
  .endm
  
  #ifdef CONFIG_SMP
@@@ -875,6 -786,7 +876,7 @@@ ENTRY(native_load_gs_index
        popfq
        ret
  END(native_load_gs_index)
+ EXPORT_SYMBOL(native_load_gs_index)
  
        _ASM_EXTABLE(.Lgs_change, bad_gs)
        .section .fixup, "ax"
@@@ -1077,6 -989,7 +1079,6 @@@ ENTRY(error_entry
        testb   $3, CS+8(%rsp)
        jz      .Lerror_kernelspace
  
 -.Lerror_entry_from_usermode_swapgs:
        /*
         * We entered from user mode or we're pretending to have entered
         * from user mode due to an IRET fault.
         * gsbase and proceed.  We'll fix up the exception and land in
         * .Lgs_change's error handler with kernel gsbase.
         */
 -      jmp     .Lerror_entry_from_usermode_swapgs
 +      SWAPGS
 +      jmp .Lerror_entry_done
  
  .Lbstep_iret:
        /* Fix truncated RIP */
@@@ -1148,7 -1060,7 +1150,7 @@@ END(error_entry
  
  
  /*
 - * On entry, EBS is a "return to kernel mode" flag:
 + * On entry, EBX is a "return to kernel mode" flag:
   *   1: already in kernel mode, don't need SWAPGS
   *   0: user gsbase is loaded, we need SWAPGS and standard preparation for return to usermode
   */
diff --combined arch/x86/kernel/Makefile
@@@ -46,9 -46,7 +46,7 @@@ obj-$(CONFIG_MODIFY_LDT_SYSCALL)      += ldt
  obj-y                 += setup.o x86_init.o i8259.o irqinit.o jump_label.o
  obj-$(CONFIG_IRQ_WORK)  += irq_work.o
  obj-y                 += probe_roms.o
- obj-$(CONFIG_X86_32)  += i386_ksyms_32.o
- obj-$(CONFIG_X86_64)  += sys_x86_64.o x8664_ksyms_64.o
- obj-$(CONFIG_X86_64)  += mcount_64.o
+ obj-$(CONFIG_X86_64)  += sys_x86_64.o mcount_64.o
  obj-$(CONFIG_X86_ESPFIX64)    += espfix_64.o
  obj-$(CONFIG_SYSFS)   += ksysfs.o
  obj-y                 += bootflag.o e820.o
@@@ -83,7 -81,6 +81,7 @@@ obj-$(CONFIG_X86_MPPARSE)     += mpparse.
  obj-y                         += apic/
  obj-$(CONFIG_X86_REBOOTFIXUPS)        += reboot_fixups_32.o
  obj-$(CONFIG_DYNAMIC_FTRACE)  += ftrace.o
 +obj-$(CONFIG_LIVEPATCH)       += livepatch.o
  obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
  obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
  obj-$(CONFIG_X86_TSC)         += trace_clock.o
@@@ -126,12 -123,6 +124,12 @@@ obj-$(CONFIG_EFI)                        += sysfb_efi.
  obj-$(CONFIG_PERF_EVENTS)             += perf_regs.o
  obj-$(CONFIG_TRACING)                 += tracepoint.o
  
 +ifdef CONFIG_FRAME_POINTER
 +obj-y                                 += unwind_frame.o
 +else
 +obj-y                                 += unwind_guess.o
 +endif
 +
  ###
  # 64 bit specific files
  ifeq ($(CONFIG_X86_64),y)
@@@ -23,6 -23,7 +23,7 @@@
  #include <asm/percpu.h>
  #include <asm/nops.h>
  #include <asm/bootparam.h>
+ #include <asm/export.h>
  
  /* Physical address */
  #define pa(X) ((X) - __PAGE_OFFSET)
@@@ -94,7 -95,7 +95,7 @@@ RESERVE_BRK(pagetables, INIT_MAP_SIZE
   */
  __HEAD
  ENTRY(startup_32)
 -      movl pa(stack_start),%ecx
 +      movl pa(initial_stack),%ecx
        
        /* test KEEP_SEGMENTS flag to see if the bootloader is asking
                us to not reload segments */
@@@ -286,7 -287,7 +287,7 @@@ num_subarch_entries = (. - subarch_entr
   * start_secondary().
   */
  ENTRY(start_cpu0)
 -      movl stack_start, %ecx
 +      movl initial_stack, %ecx
        movl %ecx, %esp
        jmp  *(initial_code)
  ENDPROC(start_cpu0)
@@@ -307,7 -308,7 +308,7 @@@ ENTRY(startup_32_smp
        movl %eax,%es
        movl %eax,%fs
        movl %eax,%gs
 -      movl pa(stack_start),%ecx
 +      movl pa(initial_stack),%ecx
        movl %eax,%ss
        leal -__PAGE_OFFSET(%ecx),%esp
  
@@@ -673,6 -674,7 +674,7 @@@ ENTRY(empty_zero_page
        .fill 4096,1,0
  ENTRY(swapper_pg_dir)
        .fill 1024,4,0
+ EXPORT_SYMBOL(empty_zero_page)
  
  /*
   * This starts the data section.
@@@ -703,7 -705,7 +705,7 @@@ ENTRY(initial_page_table
  
  .data
  .balign 4
 -ENTRY(stack_start)
 +ENTRY(initial_stack)
        .long init_thread_union+THREAD_SIZE
  
  __INITRODATA
@@@ -21,6 -21,7 +21,7 @@@
  #include <asm/percpu.h>
  #include <asm/nops.h>
  #include "../entry/calling.h"
+ #include <asm/export.h>
  
  #ifdef CONFIG_PARAVIRT
  #include <asm/asm-offsets.h>
@@@ -66,7 -67,7 +67,7 @@@ startup_64
         */
  
        /*
 -       * Setup stack for verify_cpu(). "-8" because stack_start is defined
 +       * Setup stack for verify_cpu(). "-8" because initial_stack is defined
         * this way, see below. Our best guess is a NULL ptr for stack
         * termination heuristics and we don't want to break anything which
         * might depend on it (kgdb, ...).
@@@ -226,7 -227,7 +227,7 @@@ ENTRY(secondary_startup_64
        movq    %rax, %cr0
  
        /* Setup a boot time stack */
 -      movq stack_start(%rip), %rsp
 +      movq initial_stack(%rip), %rsp
  
        /* zero EFLAGS after setting rsp */
        pushq $0
@@@ -310,7 -311,7 +311,7 @@@ ENDPROC(secondary_startup_64
   * start_secondary().
   */
  ENTRY(start_cpu0)
 -      movq stack_start(%rip),%rsp
 +      movq initial_stack(%rip),%rsp
        movq    initial_code(%rip),%rax
        pushq   $0              # fake return address to stop unwinder
        pushq   $__KERNEL_CS    # set correct cs
  ENDPROC(start_cpu0)
  #endif
  
 -      /* SMP bootup changes these two */
 +      /* Both SMP bootup and ACPI suspend change these variables */
        __REFDATA
        .balign 8
        GLOBAL(initial_code)
        .quad   x86_64_start_kernel
        GLOBAL(initial_gs)
        .quad   INIT_PER_CPU_VAR(irq_stack_union)
 -
 -      GLOBAL(stack_start)
 +      GLOBAL(initial_stack)
        .quad  init_thread_union+THREAD_SIZE-8
 -      .word  0
        __FINITDATA
  
  bad_address:
@@@ -486,10 -489,12 +487,12 @@@ early_gdt_descr_base
  ENTRY(phys_base)
        /* This must match the first entry in level2_kernel_pgt */
        .quad   0x0000000000000000
+ EXPORT_SYMBOL(phys_base)
  
  #include "../../x86/xen/xen-head.S"
        
        __PAGE_ALIGNED_BSS
  NEXT_PAGE(empty_zero_page)
        .skip PAGE_SIZE
+ EXPORT_SYMBOL(empty_zero_page)
  
diff --combined arch/x86/lib/hweight.S
@@@ -1,4 -1,5 +1,5 @@@
  #include <linux/linkage.h>
+ #include <asm/export.h>
  
  #include <asm/asm.h>
  
@@@ -32,10 -33,10 +33,11 @@@ ENTRY(__sw_hweight32
        __ASM_SIZE(pop,) %__ASM_REG(dx)
        ret
  ENDPROC(__sw_hweight32)
+ EXPORT_SYMBOL(__sw_hweight32)
  
  ENTRY(__sw_hweight64)
  #ifdef CONFIG_X86_64
 +      pushq   %rdi
        pushq   %rdx
  
        movq    %rdi, %rdx                      # w -> t
@@@ -61,7 -62,6 +63,7 @@@
        shrq    $56, %rax                       # w = w_tmp >> 56
  
        popq    %rdx
 +      popq    %rdi
        ret
  #else /* CONFIG_X86_32 */
        /* We're getting an u64 arg in (%eax,%edx): unsigned long hweight64(__u64 w) */
@@@ -77,3 -77,4 +79,4 @@@
        ret
  #endif
  ENDPROC(__sw_hweight64)
+ EXPORT_SYMBOL(__sw_hweight64)
diff --combined arch/x86/lib/memcpy_64.S
@@@ -4,6 -4,7 +4,7 @@@
  #include <asm/errno.h>
  #include <asm/cpufeatures.h>
  #include <asm/alternative-asm.h>
+ #include <asm/export.h>
  
  /*
   * We build a jump to memcpy_orig by default which gets NOPped out on
@@@ -40,6 -41,8 +41,8 @@@ ENTRY(memcpy
        ret
  ENDPROC(memcpy)
  ENDPROC(__memcpy)
+ EXPORT_SYMBOL(memcpy)
+ EXPORT_SYMBOL(__memcpy)
  
  /*
   * memcpy_erms() - enhanced fast string memcpy. This is faster and
@@@ -181,11 -184,11 +184,11 @@@ ENDPROC(memcpy_orig
  
  #ifndef CONFIG_UML
  /*
 - * memcpy_mcsafe - memory copy with machine check exception handling
 + * memcpy_mcsafe_unrolled - memory copy with machine check exception handling
   * Note that we only catch machine checks when reading the source addresses.
   * Writes to target are posted and don't generate machine checks.
   */
 -ENTRY(memcpy_mcsafe)
 +ENTRY(memcpy_mcsafe_unrolled)
        cmpl $8, %edx
        /* Less than 8 bytes? Go to byte copy loop */
        jb .L_no_whole_words
  .L_done_memcpy_trap:
        xorq %rax, %rax
        ret
 -ENDPROC(memcpy_mcsafe)
 -EXPORT_SYMBOL_GPL(memcpy_mcsafe)
 +ENDPROC(memcpy_mcsafe_unrolled)
++EXPORT_SYMBOL_GPL(memcpy_mcsafe_unrolled)
  
        .section .fixup, "ax"
        /* Return -EFAULT for any failure */
        *(.dtb.init.rodata)                                             \
        VMLINUX_SYMBOL(__dtb_end) = .;
  
- /* .data section */
+ /*
+  * .data section
+  * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections generates
+  * .data.identifier which needs to be pulled in with .data, but don't want to
+  * pull in .data..stuff which has its own requirements. Same for bss.
+  */
  #define DATA_DATA                                                     \
-       *(.data)                                                        \
+       *(.data .data.[0-9a-zA-Z_]*)                                    \
        *(.ref.data)                                                    \
        *(.data..shared_aligned) /* percpu related */                   \
        MEM_KEEP(init.data)                                             \
        /* Kernel symbol table: Normal symbols */                       \
        __ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {         \
                VMLINUX_SYMBOL(__start___ksymtab) = .;                  \
-               *(SORT(___ksymtab+*))                                   \
+               KEEP(*(SORT(___ksymtab+*)))                             \
                VMLINUX_SYMBOL(__stop___ksymtab) = .;                   \
        }                                                               \
                                                                        \
        /* Kernel symbol table: GPL-only symbols */                     \
        __ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {     \
                VMLINUX_SYMBOL(__start___ksymtab_gpl) = .;              \
-               *(SORT(___ksymtab_gpl+*))                               \
+               KEEP(*(SORT(___ksymtab_gpl+*)))                         \
                VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;               \
        }                                                               \
                                                                        \
        /* Kernel symbol table: Normal unused symbols */                \
        __ksymtab_unused  : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) {  \
                VMLINUX_SYMBOL(__start___ksymtab_unused) = .;           \
-               *(SORT(___ksymtab_unused+*))                            \
+               KEEP(*(SORT(___ksymtab_unused+*)))                      \
                VMLINUX_SYMBOL(__stop___ksymtab_unused) = .;            \
        }                                                               \
                                                                        \
        /* Kernel symbol table: GPL-only unused symbols */              \
        __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \
                VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .;       \
-               *(SORT(___ksymtab_unused_gpl+*))                        \
+               KEEP(*(SORT(___ksymtab_unused_gpl+*)))                  \
                VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .;        \
        }                                                               \
                                                                        \
        /* Kernel symbol table: GPL-future-only symbols */              \
        __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
                VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .;       \
-               *(SORT(___ksymtab_gpl_future+*))                        \
+               KEEP(*(SORT(___ksymtab_gpl_future+*)))                  \
                VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .;        \
        }                                                               \
                                                                        \
        /* Kernel symbol table: Normal symbols */                       \
        __kcrctab         : AT(ADDR(__kcrctab) - LOAD_OFFSET) {         \
                VMLINUX_SYMBOL(__start___kcrctab) = .;                  \
-               *(SORT(___kcrctab+*))                                   \
+               KEEP(*(SORT(___kcrctab+*)))                             \
                VMLINUX_SYMBOL(__stop___kcrctab) = .;                   \
        }                                                               \
                                                                        \
        /* Kernel symbol table: GPL-only symbols */                     \
        __kcrctab_gpl     : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) {     \
                VMLINUX_SYMBOL(__start___kcrctab_gpl) = .;              \
-               *(SORT(___kcrctab_gpl+*))                               \
+               KEEP(*(SORT(___kcrctab_gpl+*)))                         \
                VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .;               \
        }                                                               \
                                                                        \
        /* Kernel symbol table: Normal unused symbols */                \
        __kcrctab_unused  : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) {  \
                VMLINUX_SYMBOL(__start___kcrctab_unused) = .;           \
-               *(SORT(___kcrctab_unused+*))                            \
+               KEEP(*(SORT(___kcrctab_unused+*)))                      \
                VMLINUX_SYMBOL(__stop___kcrctab_unused) = .;            \
        }                                                               \
                                                                        \
        /* Kernel symbol table: GPL-only unused symbols */              \
        __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \
                VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .;       \
-               *(SORT(___kcrctab_unused_gpl+*))                        \
+               KEEP(*(SORT(___kcrctab_unused_gpl+*)))                  \
                VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .;        \
        }                                                               \
                                                                        \
        /* Kernel symbol table: GPL-future-only symbols */              \
        __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
                VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .;       \
-               *(SORT(___kcrctab_gpl_future+*))                        \
+               KEEP(*(SORT(___kcrctab_gpl_future+*)))                  \
                VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .;        \
        }                                                               \
                                                                        \
        /* Kernel symbol table: strings */                              \
          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {       \
-               *(__ksymtab_strings)                                    \
+               KEEP(*(__ksymtab_strings))                              \
        }                                                               \
                                                                        \
        /* __*init sections */                                          \
  #define SECURITY_INIT                                                 \
        .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \
                VMLINUX_SYMBOL(__security_initcall_start) = .;          \
-               *(.security_initcall.init)                              \
+               KEEP(*(.security_initcall.init))                        \
                VMLINUX_SYMBOL(__security_initcall_end) = .;            \
        }
  
  /* .text section. Map to function alignment to avoid address changes
-  * during second ld run in second ld pass when generating System.map */
+  * during second ld run in second ld pass when generating System.map
+  * LD_DEAD_CODE_DATA_ELIMINATION option enables -ffunction-sections generates
+  * .text.identifier which needs to be pulled in with .text , but some
+  * architectures define .text.foo which is not intended to be pulled in here.
+  * Those enabling LD_DEAD_CODE_DATA_ELIMINATION must ensure they don't have
+  * conflicting section names, and must pull in .text.[0-9a-zA-Z_]* */
  #define TEXT_TEXT                                                     \
                ALIGN_FUNCTION();                                       \
                *(.text.hot .text .text.fixup .text.unlikely)           \
                *(.spinlock.text)                                       \
                VMLINUX_SYMBOL(__lock_text_end) = .;
  
 +#define CPUIDLE_TEXT                                                  \
 +              ALIGN_FUNCTION();                                       \
 +              VMLINUX_SYMBOL(__cpuidle_text_start) = .;               \
 +              *(.cpuidle.text)                                        \
 +              VMLINUX_SYMBOL(__cpuidle_text_end) = .;
 +
  #define KPROBES_TEXT                                                  \
                ALIGN_FUNCTION();                                       \
                VMLINUX_SYMBOL(__kprobes_text_start) = .;               \
  
  /* init and exit section handling */
  #define INIT_DATA                                                     \
+       KEEP(*(SORT(___kentry+*)))                                      \
        *(.init.data)                                                   \
        MEM_DISCARD(init.data)                                          \
        KERNEL_CTORS()                                                  \
                BSS_FIRST_SECTIONS                                      \
                *(.bss..page_aligned)                                   \
                *(.dynbss)                                              \
-               *(.bss)                                                 \
+               *(.bss .bss.[0-9a-zA-Z_]*)                              \
                *(COMMON)                                               \
        }
  
  
  #define INIT_CALLS_LEVEL(level)                                               \
                VMLINUX_SYMBOL(__initcall##level##_start) = .;          \
-               *(.initcall##level##.init)                              \
-               *(.initcall##level##s.init)                             \
+               KEEP(*(.initcall##level##.init))                        \
+               KEEP(*(.initcall##level##s.init))                       \
  
  #define INIT_CALLS                                                    \
                VMLINUX_SYMBOL(__initcall_start) = .;                   \
-               *(.initcallearly.init)                                  \
+               KEEP(*(.initcallearly.init))                            \
                INIT_CALLS_LEVEL(0)                                     \
                INIT_CALLS_LEVEL(1)                                     \
                INIT_CALLS_LEVEL(2)                                     \
  
  #define CON_INITCALL                                                  \
                VMLINUX_SYMBOL(__con_initcall_start) = .;               \
-               *(.con_initcall.init)                                   \
+               KEEP(*(.con_initcall.init))                             \
                VMLINUX_SYMBOL(__con_initcall_end) = .;
  
  #define SECURITY_INITCALL                                             \
                VMLINUX_SYMBOL(__security_initcall_start) = .;          \
-               *(.security_initcall.init)                              \
+               KEEP(*(.security_initcall.init))                        \
                VMLINUX_SYMBOL(__security_initcall_end) = .;
  
  #ifdef CONFIG_BLK_DEV_INITRD
  #define INIT_RAM_FS                                                   \
        . = ALIGN(4);                                                   \
        VMLINUX_SYMBOL(__initramfs_start) = .;                          \
-       *(.init.ramfs)                                                  \
+       KEEP(*(.init.ramfs))                                            \
        . = ALIGN(8);                                                   \
-       *(.init.ramfs.info)
+       KEEP(*(.init.ramfs.info))
  #else
  #define INIT_RAM_FS
  #endif
diff --combined include/linux/compiler.h
@@@ -182,6 -182,29 +182,29 @@@ void ftrace_likely_update(struct ftrace
  # define unreachable() do { } while (1)
  #endif
  
+ /*
+  * KENTRY - kernel entry point
+  * This can be used to annotate symbols (functions or data) that are used
+  * without their linker symbol being referenced explicitly. For example,
+  * interrupt vector handlers, or functions in the kernel image that are found
+  * programatically.
+  *
+  * Not required for symbols exported with EXPORT_SYMBOL, or initcalls. Those
+  * are handled in their own way (with KEEP() in linker scripts).
+  *
+  * KENTRY can be avoided if the symbols in question are marked as KEEP() in the
+  * linker script. For example an architecture could KEEP() its entire
+  * boot/exception vector code rather than annotate each function and data.
+  */
+ #ifndef KENTRY
+ # define KENTRY(sym)                                          \
+       extern typeof(sym) sym;                                 \
+       static const unsigned long __kentry_##sym               \
+       __used                                                  \
+       __attribute__((section("___kentry" "+" #sym ), used))   \
+       = (unsigned long)&sym;
+ #endif
  #ifndef RELOC_HIDE
  # define RELOC_HIDE(ptr, off)                                 \
    ({ unsigned long __ptr;                                     \
@@@ -527,14 -550,13 +550,14 @@@ static __always_inline void __write_onc
   * object's lifetime is managed by something other than RCU.  That
   * "something other" might be reference counting or simple immortality.
   *
 - * The seemingly unused void * variable is to validate @p is indeed a pointer
 - * type. All pointer types silently cast to void *.
 + * The seemingly unused variable ___typecheck_p validates that @p is
 + * indeed a pointer type by using a pointer to typeof(*p) as the type.
 + * Taking a pointer to typeof(*p) again is needed in case p is void *.
   */
  #define lockless_dereference(p) \
  ({ \
        typeof(p) _________p1 = READ_ONCE(p); \
 -      __maybe_unused const void * const _________p2 = _________p1; \
 +      typeof(*(p)) *___typecheck_p __maybe_unused; \
        smp_read_barrier_depends(); /* Dependency order vs. p above. */ \
        (_________p1); \
  })
diff --combined include/linux/export.h
@@@ -1,5 -1,6 +1,6 @@@
  #ifndef _LINUX_EXPORT_H
  #define _LINUX_EXPORT_H
  /*
   * Export symbols from the kernel to modules.  Forked from module.h
   * to reduce the amount of pointless cruft we feed to gcc when only
@@@ -42,27 -43,26 +43,26 @@@ extern struct module __this_module
  #ifdef CONFIG_MODVERSIONS
  /* Mark the CRC weak since genksyms apparently decides not to
   * generate a checksums for some symbols */
- #define __CRC_SYMBOL(sym, sec)                                        \
-       extern __visible void *__crc_##sym __attribute__((weak));               \
-       static const unsigned long __kcrctab_##sym              \
-       __used                                                  \
-       __attribute__((section("___kcrctab" sec "+" #sym), unused))     \
+ #define __CRC_SYMBOL(sym, sec)                                                \
+       extern __visible void *__crc_##sym __attribute__((weak));       \
+       static const unsigned long __kcrctab_##sym                      \
+       __used                                                          \
+       __attribute__((section("___kcrctab" sec "+" #sym), used))       \
        = (unsigned long) &__crc_##sym;
  #else
  #define __CRC_SYMBOL(sym, sec)
  #endif
  
  /* For every exported symbol, place a struct in the __ksymtab section */
- #define ___EXPORT_SYMBOL(sym, sec)                            \
-       extern typeof(sym) sym;                                 \
-       __CRC_SYMBOL(sym, sec)                                  \
-       static const char __kstrtab_##sym[]                     \
-       __attribute__((section("__ksymtab_strings"), aligned(1))) \
-       = VMLINUX_SYMBOL_STR(sym);                              \
-       extern const struct kernel_symbol __ksymtab_##sym;      \
-       __visible const struct kernel_symbol __ksymtab_##sym    \
-       __used                                                  \
-       __attribute__((section("___ksymtab" sec "+" #sym), unused))     \
+ #define ___EXPORT_SYMBOL(sym, sec)                                    \
+       extern typeof(sym) sym;                                         \
+       __CRC_SYMBOL(sym, sec)                                          \
+       static const char __kstrtab_##sym[]                             \
+       __attribute__((section("__ksymtab_strings"), aligned(1)))       \
+       = VMLINUX_SYMBOL_STR(sym);                                      \
+       static const struct kernel_symbol __ksymtab_##sym               \
+       __used                                                          \
+       __attribute__((section("___ksymtab" sec "+" #sym), used))       \
        = { (unsigned long)&sym, __kstrtab_##sym }
  
  #if defined(__KSYM_DEPS__)
@@@ -78,6 -78,7 +78,6 @@@
  
  #elif defined(CONFIG_TRIM_UNUSED_KSYMS)
  
 -#include <linux/kconfig.h>
  #include <generated/autoksyms.h>
  
  #define __EXPORT_SYMBOL(sym, sec)                             \
diff --combined include/linux/init.h
     discard it in modules) */
  #define __init                __section(.init.text) __cold notrace
  #define __initdata    __section(.init.data)
 -#define __initconst   __constsection(.init.rodata)
 +#define __initconst   __section(.init.rodata)
  #define __exitdata    __section(.exit.data)
  #define __exit_call   __used __section(.exitcall.exit)
  
 -/*
 - * Some architecture have tool chains which do not handle rodata attributes
 - * correctly. For those disable special sections for const, so that other
 - * architectures can annotate correctly.
 - */
 -#ifdef CONFIG_BROKEN_RODATA
 -#define __constsection(x)
 -#else
 -#define __constsection(x) __section(x)
 -#endif
 -
  /*
   * modpost check for section mismatches during the kernel build.
   * A section mismatch happens when there are references from a
@@@ -64,7 -75,7 +64,7 @@@
   */
  #define __ref            __section(.ref.text) noinline
  #define __refdata        __section(.ref.data)
 -#define __refconst       __constsection(.ref.rodata)
 +#define __refconst       __section(.ref.rodata)
  
  #ifdef MODULE
  #define __exitused
  /* Used for MEMORY_HOTPLUG */
  #define __meminit        __section(.meminit.text) __cold notrace
  #define __meminitdata    __section(.meminit.data)
 -#define __meminitconst   __constsection(.meminit.rodata)
 +#define __meminitconst   __section(.meminit.rodata)
  #define __memexit        __section(.memexit.text) __exitused __cold notrace
  #define __memexitdata    __section(.memexit.data)
 -#define __memexitconst   __constsection(.memexit.rodata)
 +#define __memexitconst   __section(.memexit.rodata)
  
  /* For assembly routines */
  #define __HEAD                .section        ".head.text","ax"
@@@ -139,24 -150,8 +139,8 @@@ extern bool initcall_debug
  
  #ifndef __ASSEMBLY__
  
- #ifdef CONFIG_LTO
- /* Work around a LTO gcc problem: when there is no reference to a variable
-  * in a module it will be moved to the end of the program. This causes
-  * reordering of initcalls which the kernel does not like.
-  * Add a dummy reference function to avoid this. The function is
-  * deleted by the linker.
-  */
- #define LTO_REFERENCE_INITCALL(x) \
-       ; /* yes this is needed */                      \
-       static __used __exit void *reference_##x(void)  \
-       {                                               \
-               return &x;                              \
-       }
- #else
- #define LTO_REFERENCE_INITCALL(x)
- #endif
- /* initcalls are now grouped by functionality into separate 
+ /*
+  * initcalls are now grouped by functionality into separate
   * subsections. Ordering inside the subsections is determined
   * by link order. 
   * For backwards compatibility, initcall() puts the call in 
   *
   * The `id' arg to __define_initcall() is needed so that multiple initcalls
   * can point at the same handler without causing duplicate-symbol build errors.
+  *
+  * Initcalls are run by placing pointers in initcall sections that the
+  * kernel iterates at runtime. The linker can do dead code / data elimination
+  * and remove that completely, so the initcall sections have to be marked
+  * as KEEP() in the linker script.
   */
  
  #define __define_initcall(fn, id) \
        static initcall_t __initcall_##fn##id __used \
-       __attribute__((__section__(".initcall" #id ".init"))) = fn; \
-       LTO_REFERENCE_INITCALL(__initcall_##fn##id)
+       __attribute__((__section__(".initcall" #id ".init"))) = fn;
  
  /*
   * Early initcalls run before initializing SMP.
  
  #define __initcall(fn) device_initcall(fn)
  
- #define __exitcall(fn) \
+ #define __exitcall(fn)                                                \
        static exitcall_t __exitcall_##fn __exit_call = fn
  
- #define console_initcall(fn) \
-       static initcall_t __initcall_##fn \
+ #define console_initcall(fn)                                  \
+       static initcall_t __initcall_##fn                       \
        __used __section(.con_initcall.init) = fn
  
- #define security_initcall(fn) \
-       static initcall_t __initcall_##fn \
+ #define security_initcall(fn)                                 \
+       static initcall_t __initcall_##fn                       \
        __used __section(.security_initcall.init) = fn
  
  struct obs_kernel_param {