mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
076f14be7f
This all started about 6 month ago with the attempt to move the Posix CPU timer heavy lifting out of the timer interrupt code and just have lockless quick checks in that code path. Trivial 5 patches. This unearthed an inconsistency in the KVM handling of task work and the review requested to move all of this into generic code so other architectures can share. Valid request and solved with another 25 patches but those unearthed inconsistencies vs. RCU and instrumentation. Digging into this made it obvious that there are quite some inconsistencies vs. instrumentation in general. The int3 text poke handling in particular was completely unprotected and with the batched update of trace events even more likely to expose to endless int3 recursion. In parallel the RCU implications of instrumenting fragile entry code came up in several discussions. The conclusion of the X86 maintainer team was to go all the way and make the protection against any form of instrumentation of fragile and dangerous code pathes enforcable and verifiable by tooling. A first batch of preparatory work hit mainline with commitd5f744f9a2
. The (almost) full solution introduced a new code section '.noinstr.text' into which all code which needs to be protected from instrumentation of all sorts goes into. Any call into instrumentable code out of this section has to be annotated. objtool has support to validate this. Kprobes now excludes this section fully which also prevents BPF from fiddling with it and all 'noinstr' annotated functions also keep ftrace off. The section, kprobes and objtool changes are already merged. The major changes coming with this are: - Preparatory cleanups - Annotating of relevant functions to move them into the noinstr.text section or enforcing inlining by marking them __always_inline so the compiler cannot misplace or instrument them. - Splitting and simplifying the idtentry macro maze so that it is now clearly separated into simple exception entries and the more interesting ones which use interrupt stacks and have the paranoid handling vs. CR3 and GS. - Move quite some of the low level ASM functionality into C code: - enter_from and exit to user space handling. The ASM code now calls into C after doing the really necessary ASM handling and the return path goes back out without bells and whistels in ASM. - exception entry/exit got the equivivalent treatment - move all IRQ tracepoints from ASM to C so they can be placed as appropriate which is especially important for the int3 recursion issue. - Consolidate the declaration and definition of entry points between 32 and 64 bit. They share a common header and macros now. - Remove the extra device interrupt entry maze and just use the regular exception entry code. - All ASM entry points except NMI are now generated from the shared header file and the corresponding macros in the 32 and 64 bit entry ASM. - The C code entry points are consolidated as well with the help of DEFINE_IDTENTRY*() macros. This allows to ensure at one central point that all corresponding entry points share the same semantics. The actual function body for most entry points is in an instrumentable and sane state. There are special macros for the more sensitive entry points, e.g. INT3 and of course the nasty paranoid #NMI, #MCE, #DB and #DF. They allow to put the whole entry instrumentation and RCU handling into safe places instead of the previous pray that it is correct approach. - The INT3 text poke handling is now completely isolated and the recursion issue banned. Aside of the entry rework this required other isolation work, e.g. the ability to force inline bsearch. - Prevent #DB on fragile entry code, entry relevant memory and disable it on NMI, #MC entry, which allowed to get rid of the nested #DB IST stack shifting hackery. - A few other cleanups and enhancements which have been made possible through this and already merged changes, e.g. consolidating and further restricting the IDT code so the IDT table becomes RO after init which removes yet another popular attack vector - About 680 lines of ASM maze are gone. There are a few open issues: - An escape out of the noinstr section in the MCE handler which needs some more thought but under the aspect that MCE is a complete trainwreck by design and the propability to survive it is low, this was not high on the priority list. - Paravirtualization When PV is enabled then objtool complains about a bunch of indirect calls out of the noinstr section. There are a few straight forward ways to fix this, but the other issues vs. general correctness were more pressing than parawitz. - KVM KVM is inconsistent as well. Patches have been posted, but they have not yet been commented on or picked up by the KVM folks. - IDLE Pretty much the same problems can be found in the low level idle code especially the parts where RCU stopped watching. This was beyond the scope of the more obvious and exposable problems and is on the todo list. The lesson learned from this brain melting exercise to morph the evolved code base into something which can be validated and understood is that once again the violation of the most important engineering principle "correctness first" has caused quite a few people to spend valuable time on problems which could have been avoided in the first place. The "features first" tinkering mindset really has to stop. With that I want to say thanks to everyone involved in contributing to this effort. Special thanks go to the following people (alphabetical order): Alexandre Chartre Andy Lutomirski Borislav Petkov Brian Gerst Frederic Weisbecker Josh Poimboeuf Juergen Gross Lai Jiangshan Macro Elver Paolo Bonzini Paul McKenney Peter Zijlstra Vitaly Kuznetsov Will Deacon -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAl7j510THHRnbHhAbGlu dXRyb25peC5kZQAKCRCmGPVMDXSYoU2WD/4refvaNm08fG7aiVYem3JJzr0+Pq5O /opwnI/1D973ApApj5W/Nd53sN5tVqOiXncSKgywRBWZxRCAGjVYypl9rjpvXu4l HlMjhEKBmWkDryxxrM98Vr7hl3hnId5laR56oFfH+G4LUsItaV6Uak/HfXZ4Mq1k iYVbEtl2CN+KJjvSgZ6Y1l853Ab5mmGvmeGNHHWCj8ZyjF3cOLoelDTQNnsb0wXM crKXBcXJSsCWKYyJ5PTvB82crQCET7Su+LgwK06w/ZbW1//2hVIjSCiN5o/V+aRJ 06BZNMj8v9tfglkN8LEQvRIjTlnEQ2sq3GxbrVtA53zxkzbBCBJQ96w8yYzQX0ux yhqQ/aIZJ1wTYEjJzSkftwLNMRHpaOUnKvJndXRKAYi+eGI7syF61qcZSYGKuAQ/ bK3b/CzU6QWr1235oTADxh4isEwxA0Pg5wtJCfDDOG0MJ9ALMSOGUkhoiz5EqpkU mzFAwfG/Uj7hRjlkms7Yj2OjZfnU7iypj63GgpXghLjr5ksRFKEOMw8e1GXltVHs zzwghUjqp2EPq0VOOQn3lp9lol5Prc3xfFHczKpO+CJW6Rpa4YVdqJmejBqJy/on Hh/T/ST3wa2qBeAw89vZIeWiUJZZCsQ0f//+2hAbzJY45Y6DuR9vbTAPb9agRgOM xg+YaCfpQqFc1A== =llba -----END PGP SIGNATURE----- Merge tag 'x86-entry-2020-06-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull x86 entry updates from Thomas Gleixner: "The x86 entry, exception and interrupt code rework This all started about 6 month ago with the attempt to move the Posix CPU timer heavy lifting out of the timer interrupt code and just have lockless quick checks in that code path. Trivial 5 patches. This unearthed an inconsistency in the KVM handling of task work and the review requested to move all of this into generic code so other architectures can share. Valid request and solved with another 25 patches but those unearthed inconsistencies vs. RCU and instrumentation. Digging into this made it obvious that there are quite some inconsistencies vs. instrumentation in general. The int3 text poke handling in particular was completely unprotected and with the batched update of trace events even more likely to expose to endless int3 recursion. In parallel the RCU implications of instrumenting fragile entry code came up in several discussions. The conclusion of the x86 maintainer team was to go all the way and make the protection against any form of instrumentation of fragile and dangerous code pathes enforcable and verifiable by tooling. A first batch of preparatory work hit mainline with commitd5f744f9a2
("Pull x86 entry code updates from Thomas Gleixner") That (almost) full solution introduced a new code section '.noinstr.text' into which all code which needs to be protected from instrumentation of all sorts goes into. Any call into instrumentable code out of this section has to be annotated. objtool has support to validate this. Kprobes now excludes this section fully which also prevents BPF from fiddling with it and all 'noinstr' annotated functions also keep ftrace off. The section, kprobes and objtool changes are already merged. The major changes coming with this are: - Preparatory cleanups - Annotating of relevant functions to move them into the noinstr.text section or enforcing inlining by marking them __always_inline so the compiler cannot misplace or instrument them. - Splitting and simplifying the idtentry macro maze so that it is now clearly separated into simple exception entries and the more interesting ones which use interrupt stacks and have the paranoid handling vs. CR3 and GS. - Move quite some of the low level ASM functionality into C code: - enter_from and exit to user space handling. The ASM code now calls into C after doing the really necessary ASM handling and the return path goes back out without bells and whistels in ASM. - exception entry/exit got the equivivalent treatment - move all IRQ tracepoints from ASM to C so they can be placed as appropriate which is especially important for the int3 recursion issue. - Consolidate the declaration and definition of entry points between 32 and 64 bit. They share a common header and macros now. - Remove the extra device interrupt entry maze and just use the regular exception entry code. - All ASM entry points except NMI are now generated from the shared header file and the corresponding macros in the 32 and 64 bit entry ASM. - The C code entry points are consolidated as well with the help of DEFINE_IDTENTRY*() macros. This allows to ensure at one central point that all corresponding entry points share the same semantics. The actual function body for most entry points is in an instrumentable and sane state. There are special macros for the more sensitive entry points, e.g. INT3 and of course the nasty paranoid #NMI, #MCE, #DB and #DF. They allow to put the whole entry instrumentation and RCU handling into safe places instead of the previous pray that it is correct approach. - The INT3 text poke handling is now completely isolated and the recursion issue banned. Aside of the entry rework this required other isolation work, e.g. the ability to force inline bsearch. - Prevent #DB on fragile entry code, entry relevant memory and disable it on NMI, #MC entry, which allowed to get rid of the nested #DB IST stack shifting hackery. - A few other cleanups and enhancements which have been made possible through this and already merged changes, e.g. consolidating and further restricting the IDT code so the IDT table becomes RO after init which removes yet another popular attack vector - About 680 lines of ASM maze are gone. There are a few open issues: - An escape out of the noinstr section in the MCE handler which needs some more thought but under the aspect that MCE is a complete trainwreck by design and the propability to survive it is low, this was not high on the priority list. - Paravirtualization When PV is enabled then objtool complains about a bunch of indirect calls out of the noinstr section. There are a few straight forward ways to fix this, but the other issues vs. general correctness were more pressing than parawitz. - KVM KVM is inconsistent as well. Patches have been posted, but they have not yet been commented on or picked up by the KVM folks. - IDLE Pretty much the same problems can be found in the low level idle code especially the parts where RCU stopped watching. This was beyond the scope of the more obvious and exposable problems and is on the todo list. The lesson learned from this brain melting exercise to morph the evolved code base into something which can be validated and understood is that once again the violation of the most important engineering principle "correctness first" has caused quite a few people to spend valuable time on problems which could have been avoided in the first place. The "features first" tinkering mindset really has to stop. With that I want to say thanks to everyone involved in contributing to this effort. Special thanks go to the following people (alphabetical order): Alexandre Chartre, Andy Lutomirski, Borislav Petkov, Brian Gerst, Frederic Weisbecker, Josh Poimboeuf, Juergen Gross, Lai Jiangshan, Macro Elver, Paolo Bonzin,i Paul McKenney, Peter Zijlstra, Vitaly Kuznetsov, and Will Deacon" * tag 'x86-entry-2020-06-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (142 commits) x86/entry: Force rcu_irq_enter() when in idle task x86/entry: Make NMI use IDTENTRY_RAW x86/entry: Treat BUG/WARN as NMI-like entries x86/entry: Unbreak __irqentry_text_start/end magic x86/entry: __always_inline CR2 for noinstr lockdep: __always_inline more for noinstr x86/entry: Re-order #DB handler to avoid *SAN instrumentation x86/entry: __always_inline arch_atomic_* for noinstr x86/entry: __always_inline irqflags for noinstr x86/entry: __always_inline debugreg for noinstr x86/idt: Consolidate idt functionality x86/idt: Cleanup trap_init() x86/idt: Use proper constants for table size x86/idt: Add comments about early #PF handling x86/idt: Mark init only functions __init x86/entry: Rename trace_hardirqs_off_prepare() x86/entry: Clarify irq_{enter,exit}_rcu() x86/entry: Remove DBn stacks x86/entry: Remove debug IDT frobbing x86/entry: Optimize local_db_save() for virt ...
454 lines
11 KiB
ArmAsm
454 lines
11 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* ld script for the x86 kernel
|
|
*
|
|
* Historic 32-bit version written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
|
|
*
|
|
* Modernisation, unification and other changes and fixes:
|
|
* Copyright (C) 2007-2009 Sam Ravnborg <sam@ravnborg.org>
|
|
*
|
|
*
|
|
* Don't define absolute symbols until and unless you know that symbol
|
|
* value is should remain constant even if kernel image is relocated
|
|
* at run time. Absolute symbols are not relocated. If symbol value should
|
|
* change if kernel is relocated, make the symbol section relative and
|
|
* put it inside the section definition.
|
|
*/
|
|
|
|
#ifdef CONFIG_X86_32
|
|
#define LOAD_OFFSET __PAGE_OFFSET
|
|
#else
|
|
#define LOAD_OFFSET __START_KERNEL_map
|
|
#endif
|
|
|
|
#define RUNTIME_DISCARD_EXIT
|
|
#define EMITS_PT_NOTE
|
|
#define RO_EXCEPTION_TABLE_ALIGN 16
|
|
|
|
#include <asm-generic/vmlinux.lds.h>
|
|
#include <asm/asm-offsets.h>
|
|
#include <asm/thread_info.h>
|
|
#include <asm/page_types.h>
|
|
#include <asm/orc_lookup.h>
|
|
#include <asm/cache.h>
|
|
#include <asm/boot.h>
|
|
|
|
#undef i386 /* in case the preprocessor is a 32bit one */
|
|
|
|
OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT)
|
|
|
|
#ifdef CONFIG_X86_32
|
|
OUTPUT_ARCH(i386)
|
|
ENTRY(phys_startup_32)
|
|
#else
|
|
OUTPUT_ARCH(i386:x86-64)
|
|
ENTRY(phys_startup_64)
|
|
#endif
|
|
|
|
jiffies = jiffies_64;
|
|
|
|
#if defined(CONFIG_X86_64)
|
|
/*
|
|
* On 64-bit, align RODATA to 2MB so we retain large page mappings for
|
|
* boundaries spanning kernel text, rodata and data sections.
|
|
*
|
|
* However, kernel identity mappings will have different RWX permissions
|
|
* to the pages mapping to text and to the pages padding (which are freed) the
|
|
* text section. Hence kernel identity mappings will be broken to smaller
|
|
* pages. For 64-bit, kernel text and kernel identity mappings are different,
|
|
* so we can enable protection checks as well as retain 2MB large page
|
|
* mappings for kernel text.
|
|
*/
|
|
#define X86_ALIGN_RODATA_BEGIN . = ALIGN(HPAGE_SIZE);
|
|
|
|
#define X86_ALIGN_RODATA_END \
|
|
. = ALIGN(HPAGE_SIZE); \
|
|
__end_rodata_hpage_align = .; \
|
|
__end_rodata_aligned = .;
|
|
|
|
#define ALIGN_ENTRY_TEXT_BEGIN . = ALIGN(PMD_SIZE);
|
|
#define ALIGN_ENTRY_TEXT_END . = ALIGN(PMD_SIZE);
|
|
|
|
/*
|
|
* This section contains data which will be mapped as decrypted. Memory
|
|
* encryption operates on a page basis. Make this section PMD-aligned
|
|
* to avoid splitting the pages while mapping the section early.
|
|
*
|
|
* Note: We use a separate section so that only this section gets
|
|
* decrypted to avoid exposing more than we wish.
|
|
*/
|
|
#define BSS_DECRYPTED \
|
|
. = ALIGN(PMD_SIZE); \
|
|
__start_bss_decrypted = .; \
|
|
*(.bss..decrypted); \
|
|
. = ALIGN(PAGE_SIZE); \
|
|
__start_bss_decrypted_unused = .; \
|
|
. = ALIGN(PMD_SIZE); \
|
|
__end_bss_decrypted = .; \
|
|
|
|
#else
|
|
|
|
#define X86_ALIGN_RODATA_BEGIN
|
|
#define X86_ALIGN_RODATA_END \
|
|
. = ALIGN(PAGE_SIZE); \
|
|
__end_rodata_aligned = .;
|
|
|
|
#define ALIGN_ENTRY_TEXT_BEGIN
|
|
#define ALIGN_ENTRY_TEXT_END
|
|
#define BSS_DECRYPTED
|
|
|
|
#endif
|
|
|
|
PHDRS {
|
|
text PT_LOAD FLAGS(5); /* R_E */
|
|
data PT_LOAD FLAGS(6); /* RW_ */
|
|
#ifdef CONFIG_X86_64
|
|
#ifdef CONFIG_SMP
|
|
percpu PT_LOAD FLAGS(6); /* RW_ */
|
|
#endif
|
|
init PT_LOAD FLAGS(7); /* RWE */
|
|
#endif
|
|
note PT_NOTE FLAGS(0); /* ___ */
|
|
}
|
|
|
|
SECTIONS
|
|
{
|
|
#ifdef CONFIG_X86_32
|
|
. = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
|
|
phys_startup_32 = ABSOLUTE(startup_32 - LOAD_OFFSET);
|
|
#else
|
|
. = __START_KERNEL;
|
|
phys_startup_64 = ABSOLUTE(startup_64 - LOAD_OFFSET);
|
|
#endif
|
|
|
|
/* Text and read-only data */
|
|
.text : AT(ADDR(.text) - LOAD_OFFSET) {
|
|
_text = .;
|
|
_stext = .;
|
|
/* bootstrapping code */
|
|
HEAD_TEXT
|
|
TEXT_TEXT
|
|
SCHED_TEXT
|
|
CPUIDLE_TEXT
|
|
LOCK_TEXT
|
|
KPROBES_TEXT
|
|
ALIGN_ENTRY_TEXT_BEGIN
|
|
ENTRY_TEXT
|
|
ALIGN_ENTRY_TEXT_END
|
|
SOFTIRQENTRY_TEXT
|
|
*(.fixup)
|
|
*(.gnu.warning)
|
|
|
|
#ifdef CONFIG_RETPOLINE
|
|
__indirect_thunk_start = .;
|
|
*(.text.__x86.indirect_thunk)
|
|
__indirect_thunk_end = .;
|
|
#endif
|
|
} :text =0xcccc
|
|
|
|
/* End of text section, which should occupy whole number of pages */
|
|
_etext = .;
|
|
. = ALIGN(PAGE_SIZE);
|
|
|
|
X86_ALIGN_RODATA_BEGIN
|
|
RO_DATA(PAGE_SIZE)
|
|
X86_ALIGN_RODATA_END
|
|
|
|
/* Data */
|
|
.data : AT(ADDR(.data) - LOAD_OFFSET) {
|
|
/* Start of data section */
|
|
_sdata = .;
|
|
|
|
/* init_task */
|
|
INIT_TASK_DATA(THREAD_SIZE)
|
|
|
|
#ifdef CONFIG_X86_32
|
|
/* 32 bit has nosave before _edata */
|
|
NOSAVE_DATA
|
|
#endif
|
|
|
|
PAGE_ALIGNED_DATA(PAGE_SIZE)
|
|
|
|
CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
|
|
|
|
DATA_DATA
|
|
CONSTRUCTORS
|
|
|
|
/* rarely changed data like cpu maps */
|
|
READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES)
|
|
|
|
/* End of data section */
|
|
_edata = .;
|
|
} :data
|
|
|
|
BUG_TABLE
|
|
|
|
ORC_UNWIND_TABLE
|
|
|
|
. = ALIGN(PAGE_SIZE);
|
|
__vvar_page = .;
|
|
|
|
.vvar : AT(ADDR(.vvar) - LOAD_OFFSET) {
|
|
/* work around gold bug 13023 */
|
|
__vvar_beginning_hack = .;
|
|
|
|
/* Place all vvars at the offsets in asm/vvar.h. */
|
|
#define EMIT_VVAR(name, offset) \
|
|
. = __vvar_beginning_hack + offset; \
|
|
*(.vvar_ ## name)
|
|
#include <asm/vvar.h>
|
|
#undef EMIT_VVAR
|
|
|
|
/*
|
|
* Pad the rest of the page with zeros. Otherwise the loader
|
|
* can leave garbage here.
|
|
*/
|
|
. = __vvar_beginning_hack + PAGE_SIZE;
|
|
} :data
|
|
|
|
. = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE);
|
|
|
|
/* Init code and data - will be freed after init */
|
|
. = ALIGN(PAGE_SIZE);
|
|
.init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
|
|
__init_begin = .; /* paired with __init_end */
|
|
}
|
|
|
|
#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
|
|
/*
|
|
* percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
|
|
* output PHDR, so the next output section - .init.text - should
|
|
* start another segment - init.
|
|
*/
|
|
PERCPU_VADDR(INTERNODE_CACHE_BYTES, 0, :percpu)
|
|
ASSERT(SIZEOF(.data..percpu) < CONFIG_PHYSICAL_START,
|
|
"per-CPU data too large - increase CONFIG_PHYSICAL_START")
|
|
#endif
|
|
|
|
INIT_TEXT_SECTION(PAGE_SIZE)
|
|
#ifdef CONFIG_X86_64
|
|
:init
|
|
#endif
|
|
|
|
/*
|
|
* Section for code used exclusively before alternatives are run. All
|
|
* references to such code must be patched out by alternatives, normally
|
|
* by using X86_FEATURE_ALWAYS CPU feature bit.
|
|
*
|
|
* See static_cpu_has() for an example.
|
|
*/
|
|
.altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) {
|
|
*(.altinstr_aux)
|
|
}
|
|
|
|
INIT_DATA_SECTION(16)
|
|
|
|
.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
|
|
__x86_cpu_dev_start = .;
|
|
*(.x86_cpu_dev.init)
|
|
__x86_cpu_dev_end = .;
|
|
}
|
|
|
|
#ifdef CONFIG_X86_INTEL_MID
|
|
.x86_intel_mid_dev.init : AT(ADDR(.x86_intel_mid_dev.init) - \
|
|
LOAD_OFFSET) {
|
|
__x86_intel_mid_dev_start = .;
|
|
*(.x86_intel_mid_dev.init)
|
|
__x86_intel_mid_dev_end = .;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* start address and size of operations which during runtime
|
|
* can be patched with virtualization friendly instructions or
|
|
* baremetal native ones. Think page table operations.
|
|
* Details in paravirt_types.h
|
|
*/
|
|
. = ALIGN(8);
|
|
.parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
|
|
__parainstructions = .;
|
|
*(.parainstructions)
|
|
__parainstructions_end = .;
|
|
}
|
|
|
|
/*
|
|
* struct alt_inst entries. From the header (alternative.h):
|
|
* "Alternative instructions for different CPU types or capabilities"
|
|
* Think locking instructions on spinlocks.
|
|
*/
|
|
. = ALIGN(8);
|
|
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
|
|
__alt_instructions = .;
|
|
*(.altinstructions)
|
|
__alt_instructions_end = .;
|
|
}
|
|
|
|
/*
|
|
* And here are the replacement instructions. The linker sticks
|
|
* them as binary blobs. The .altinstructions has enough data to
|
|
* get the address and the length of them to patch the kernel safely.
|
|
*/
|
|
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
|
|
*(.altinstr_replacement)
|
|
}
|
|
|
|
/*
|
|
* struct iommu_table_entry entries are injected in this section.
|
|
* It is an array of IOMMUs which during run time gets sorted depending
|
|
* on its dependency order. After rootfs_initcall is complete
|
|
* this section can be safely removed.
|
|
*/
|
|
.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
|
|
__iommu_table = .;
|
|
*(.iommu_table)
|
|
__iommu_table_end = .;
|
|
}
|
|
|
|
. = ALIGN(8);
|
|
.apicdrivers : AT(ADDR(.apicdrivers) - LOAD_OFFSET) {
|
|
__apicdrivers = .;
|
|
*(.apicdrivers);
|
|
__apicdrivers_end = .;
|
|
}
|
|
|
|
. = ALIGN(8);
|
|
/*
|
|
* .exit.text is discarded at runtime, not link time, to deal with
|
|
* references from .altinstructions
|
|
*/
|
|
.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
|
|
EXIT_TEXT
|
|
}
|
|
|
|
.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
|
|
EXIT_DATA
|
|
}
|
|
|
|
#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
|
|
PERCPU_SECTION(INTERNODE_CACHE_BYTES)
|
|
#endif
|
|
|
|
. = ALIGN(PAGE_SIZE);
|
|
|
|
/* freed after init ends here */
|
|
.init.end : AT(ADDR(.init.end) - LOAD_OFFSET) {
|
|
__init_end = .;
|
|
}
|
|
|
|
/*
|
|
* smp_locks might be freed after init
|
|
* start/end must be page aligned
|
|
*/
|
|
. = ALIGN(PAGE_SIZE);
|
|
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
|
|
__smp_locks = .;
|
|
*(.smp_locks)
|
|
. = ALIGN(PAGE_SIZE);
|
|
__smp_locks_end = .;
|
|
}
|
|
|
|
#ifdef CONFIG_X86_64
|
|
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
|
|
NOSAVE_DATA
|
|
}
|
|
#endif
|
|
|
|
/* BSS */
|
|
. = ALIGN(PAGE_SIZE);
|
|
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
|
|
__bss_start = .;
|
|
*(.bss..page_aligned)
|
|
*(BSS_MAIN)
|
|
BSS_DECRYPTED
|
|
. = ALIGN(PAGE_SIZE);
|
|
__bss_stop = .;
|
|
}
|
|
|
|
/*
|
|
* The memory occupied from _text to here, __end_of_kernel_reserve, is
|
|
* automatically reserved in setup_arch(). Anything after here must be
|
|
* explicitly reserved using memblock_reserve() or it will be discarded
|
|
* and treated as available memory.
|
|
*/
|
|
__end_of_kernel_reserve = .;
|
|
|
|
. = ALIGN(PAGE_SIZE);
|
|
.brk : AT(ADDR(.brk) - LOAD_OFFSET) {
|
|
__brk_base = .;
|
|
. += 64 * 1024; /* 64k alignment slop space */
|
|
*(.brk_reservation) /* areas brk users have reserved */
|
|
__brk_limit = .;
|
|
}
|
|
|
|
. = ALIGN(PAGE_SIZE); /* keep VO_INIT_SIZE page aligned */
|
|
_end = .;
|
|
|
|
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
|
/*
|
|
* Early scratch/workarea section: Lives outside of the kernel proper
|
|
* (_text - _end).
|
|
*
|
|
* Resides after _end because even though the .brk section is after
|
|
* __end_of_kernel_reserve, the .brk section is later reserved as a
|
|
* part of the kernel. Since it is located after __end_of_kernel_reserve
|
|
* it will be discarded and become part of the available memory. As
|
|
* such, it can only be used by very early boot code and must not be
|
|
* needed afterwards.
|
|
*
|
|
* Currently used by SME for performing in-place encryption of the
|
|
* kernel during boot. Resides on a 2MB boundary to simplify the
|
|
* pagetable setup used for SME in-place encryption.
|
|
*/
|
|
. = ALIGN(HPAGE_SIZE);
|
|
.init.scratch : AT(ADDR(.init.scratch) - LOAD_OFFSET) {
|
|
__init_scratch_begin = .;
|
|
*(.init.scratch)
|
|
. = ALIGN(HPAGE_SIZE);
|
|
__init_scratch_end = .;
|
|
}
|
|
#endif
|
|
|
|
STABS_DEBUG
|
|
DWARF_DEBUG
|
|
|
|
DISCARDS
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_X86_32
|
|
/*
|
|
* The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
|
|
*/
|
|
. = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
|
|
"kernel image bigger than KERNEL_IMAGE_SIZE");
|
|
#else
|
|
/*
|
|
* Per-cpu symbols which need to be offset from __per_cpu_load
|
|
* for the boot processor.
|
|
*/
|
|
#define INIT_PER_CPU(x) init_per_cpu__##x = ABSOLUTE(x) + __per_cpu_load
|
|
INIT_PER_CPU(gdt_page);
|
|
INIT_PER_CPU(fixed_percpu_data);
|
|
INIT_PER_CPU(irq_stack_backing_store);
|
|
|
|
/*
|
|
* Build-time check on the image size:
|
|
*/
|
|
. = ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
|
|
"kernel image bigger than KERNEL_IMAGE_SIZE");
|
|
|
|
#ifdef CONFIG_SMP
|
|
. = ASSERT((fixed_percpu_data == 0),
|
|
"fixed_percpu_data is not at start of per-cpu area");
|
|
#endif
|
|
|
|
#endif /* CONFIG_X86_32 */
|
|
|
|
#ifdef CONFIG_KEXEC_CORE
|
|
#include <asm/kexec.h>
|
|
|
|
. = ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE,
|
|
"kexec control code size is too big");
|
|
#endif
|
|
|