x86/boot tree changes for v3.19
Subsystems (2)
Linus,
Please pull the latest x86-boot-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-boot-for-linus
# HEAD: 97b67ae559947f1e208439a1bf6a734da3087006 x86-64: Use RIP-relative addressing for most per-CPU accesses
This tree contains a bootable images documentation update plus three slightly misplaced x86/asm percpu changes/optimizations.
Thanks,
Ingo
------------------>
Jan Beulich (3):
x86: Convert a few more per-CPU items to read-mostly ones
x86-64: Handle PC-relative relocations on per-CPU data
x86-64: Use RIP-relative addressing for most per-CPU accesses
Kees Cook (1):
x86, boot: Document intermediates more clearly
arch/x86/boot/compressed/Makefile | 12 ++++++++ arch/x86/boot/compressed/misc.c | 14 ++++++++- arch/x86/include/asm/percpu.h | 61 +++++++++++++++++++++++++++++---------- arch/x86/include/asm/processor.h | 4 +-- arch/x86/kernel/setup_percpu.c | 2 +- arch/x86/kernel/smpboot.c | 2 +- arch/x86/kernel/vmlinux.lds.S | 2 ++ arch/x86/tools/relocs.c | 36 +++++++++++++++++------ 8 files changed, 103 insertions(+), 30 deletions(-)
arch/x86/boot/compressed/Makefile +12 -0
@@ -3,6 +3,18 @@ # # create a compressed vmlinux image from the original vmlinux # +# vmlinuz is: +# decompression code (*.o) +# asm globals (piggy.S), including: +# vmlinux.bin.(gz|bz2|lzma|...) +# +# vmlinux.bin is: +# vmlinux stripped of debugging and comments +# vmlinux.bin.all is: +# vmlinux.bin + vmlinux.relocs +# vmlinux.bin.(gz|bz2|lzma|...) is: +# (see scripts/Makefile.lib size_append) +# compressed vmlinux.bin.all + u32 size of vmlinux.bin.all targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
arch/x86/boot/compressed/misc.c +13 -1
@@ -260,7 +260,7 @@ static void handle_relocations(void *output, unsigned long output_len)/* * Process relocations: 32 bit relocations first then 64 bit after. -* Two sets of binary relocations are added to the end of the kernel +* Three sets of binary relocations are added to the end of the kernel * before compression. Each relocation table entry is the kernel * address of the location which needs to be updated stored as a * 32-bit value which is sign extended to 64 bits.
@@ -270,6 +270,8 @@ static void handle_relocations(void *output, unsigned long output_len)* kernel bits... * 0 - zero terminator for 64 bit relocations * 64 bit relocation repeated +* 0 - zero terminator for inverse 32 bit relocations +* 32 bit inverse relocation repeated * 0 - zero terminator for 32 bit relocations * 32 bit relocation repeated *
@@ -286,6 +288,16 @@ static void handle_relocations(void *output, unsigned long output_len) *(uint32_t *)ptr += delta; }#ifdef CONFIG_X86_64 +while (*--reloc) { +long extended = *reloc; + extended += map; + + ptr = (unsigned long )extended; +if (ptr < min_addr || ptr > max_addr) +error ("inverse 32-bit relocation outside of kernel!\n" ); + + *(int32_t *)ptr -= delta; + }for (reloc--; *reloc; reloc--) {long extended = *reloc; extended += map;
arch/x86/include/asm/percpu.h +45 -16
122 lines not on this page · raw message
arch/x86/include/asm/processor.h +2 -2
@@ -127,7 +127,7 @@ struct cpuinfo_x86 {/* Index into per_cpu list: */ u16 cpu_index;u32 microcode; -} __attribute__((__aligned__(SMP_CACHE_BYTES))); +};#define X86_VENDOR_INTEL 0#define X86_VENDOR_CYRIX 1
@@ -151,7 +151,7 @@ extern __u32 cpu_caps_cleared[NCAPINTS];extern __u32 cpu_caps_set[NCAPINTS ];#ifdef CONFIG_SMP -DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); +DECLARE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);#define cpu_data (cpu) per_cpu(cpu_info, cpu)#else #define cpu_info boot_cpu_data
arch/x86/kernel/setup_percpu.c +1 -1
@@ -30,7 +30,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);#define BOOT_PERCPU_OFFSET 0#endif -DEFINE_PER_CPU(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET; +DEFINE_PER_CPU_READ_MOSTLY(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;EXPORT_PER_CPU_SYMBOL (this_cpu_off);unsigned long __per_cpu_offset[NR_CPUS ]__read_mostly = {
arch/x86/kernel/smpboot.c +1 -1
@@ -99,7 +99,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map);DEFINE_PER_CPU_READ_MOSTLY (cpumask_var_t, cpu_llc_shared_map);/* Per CPU bogomips and other parameters */ -DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); +DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);EXPORT_PER_CPU_SYMBOL (cpu_info);atomic_t init_deasserted;
arch/x86/kernel/vmlinux.lds.S +2 -0
@@ -186,6 +186,8 @@ SECTIONS * 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)
arch/x86/tools/relocs.c +27 -9
@@ -20,7 +20,10 @@ struct relocs {static struct relocs relocs16;static struct relocs relocs32; +#if ELF_BITS ==64 +static struct relocs relocs32neg;static struct relocs relocs64; +#endif struct section {Elf_Shdr shdr;
@@ -762,11 +765,16 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,switch (r_type) {case R_X86_64_NONE : +/* NONE can be ignored. */ +break ; +case R_X86_64_PC32 :/* -* NONE can be ignored and PC relative relocations don't -* need to be adjusted. +* PC relative relocations don't need to be adjusted unless +* referencing a percpu symbol. */ +if (is_percpu_sym (sym, symname)) +add_reloc (&relocs32neg, offset);break ;case R_X86_64_32 :
@@ -986,7 +994,10 @@ static void emit_relocs(int as_text, int use_real_mode)/* Order the relocations for more efficient processing */ sort_relocs (&relocs16);sort_relocs (&relocs32); +#if ELF_BITS ==64 +sort_relocs (&relocs32neg);sort_relocs (&relocs64); +#endif /* Print the relocations */ if (as_text) {
@@ -1007,14 +1018,21 @@ static void emit_relocs(int as_text, int use_real_mode)for (i =0 ; i < relocs32.count; i++)write_reloc (relocs32.offset[i], stdout); }else { -if (ELF_BITS ==64 ) { -/* Print a stop */ -write_reloc (0 , stdout); +#if ELF_BITS ==64 +/* Print a stop */ +write_reloc (0 , stdout); -/* Now print each relocation */ -for (i =0 ; i < relocs64.count; i++) -write_reloc (relocs64.offset[i], stdout); - } +/* Now print each relocation */ +for (i =0 ; i < relocs64.count; i++) +write_reloc (relocs64.offset[i], stdout); + +/* Print a stop */ +write_reloc (0 , stdout); + +/* Now print each inverse 32-bit relocation */ +for (i =0 ; i < relocs32neg.count; i++) +write_reloc (relocs32neg.offset[i], stdout); +#endif /* Print a stop */ write_reloc (0 , stdout);