x86/boot changes for v4.7
Subsystems (9)
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: d2d3462f9f08da364c8fbd41e8e32229d610d49d x86/KASLR: Clarify purpose of each get_random_long()
The biggest changes in this cycle were:
- prepare for more KASLR related changes, by restructuring, cleaning up and fixing the existing boot code. (Kees Cook, Baoquan He, Yinghai Lu)
- simplifly/concentrate subarch handling code, eliminate paravirt_enabled() usage. (Luis R. Rodriguez)
out-of-topic modifications in x86-boot-for-linus:
---------------------------------------------------
drivers/pnp/pnpbios/core.c # 80dfd83dfab6: x86, drivers/pnpbios: Replac
include/linux/pnp.h # 80dfd83dfab6: x86, drivers/pnpbios: Replac
tools/lguest/lguest.c # 46504590321d: tools/lguest: Force disable
# 907bb6557974: tools/lguest: Make lguest laThanks,
Ingo
------------------>
Baoquan He (5):
x86/KASLR: Update description for decompressor worst case size x86/KASLR: Drop CONFIG_RANDOMIZE_BASE_MAX_OFFSET x86/KASLR: Handle kernel relocations above 2G correctly x86/KASLR: Add 'struct slot_area' to manage random_addr slots x86/KASLR: Add virtual address choosing function
Borislav Petkov (2):
x86/boot: Simplify pointer casting in choose_random_location() x86/boot: Comment what finalize_identity_maps() does
Kees Cook (19):
x86/KASLR: Rename aslr.c to kaslr.c
x86/boot: Rename "real_mode" to "boot_params" x86/boot: Clarify purpose of functions in misc.c x86/KASLR: Clarify purpose of kaslr.c x86/KASLR: Rename "random" to "random_addr" x86/boot: Clean up things used by decompressors x86/boot: Make memcpy() handle overlaps x86/KASLR: Warn when KASLR is disabled x86/boot: Rename overlapping memcpy() to memmove() x86/boot: Extract error reporting functions x86/boot: Warn on future overlapping memcpy() use x86/boot: Clean up pointer casting
x86/KASLR: Improve comments around the mem_avoid[] logic x86/boot: Clean up indenting for asm/boot.h x86/KASLR: Build identity mappings on demand x86/KASLR: Initialize mapping_info every time x86/boot: Add missing file header comments x86/KASLR: Return earliest overlap when avoiding regions x86/KASLR: Clarify purpose of each get_random_long()
Luis R. Rodriguez (16):
x86/boot: Enumerate documentation for the x86 hardware_subarch x86/xen: Use X86_SUBARCH_XEN for PV guest boots
tools/lguest: Make lguest launcher use X86_SUBARCH_LGUEST explicitly x86/rtc: Replace paravirt rtc check with platform legacy quirk x86/ACPI: Move ACPI_FADT_NO_CMOS_RTC check to ACPI boot code x86/init: Use a platform legacy quirk for EBDA
tools/lguest: Force disable tboot and APM
x86/apm32: Remove paravirt_enabled() use
x86/tboot: Remove paravirt_enabled() use
x86/cpu/intel: Remove not needed paravirt_enabled() use for F00F work around x86, drivers/pnpbios: Replace paravirt_enabled() check with legacy device check x86/ACPI: Parse ACPI_FADT_LEGACY_DEVICES
x86/init: Rename EBDA code file
x86/paravirt: Remove paravirt_enabled()
x86/init: Disable pnpbios for X86_SUBARCH_INTEL_MID
x86/init: Disable pnpbios and rtc for X86_SUBARCH_CE4100
Yinghai Lu (8):
x86/KASLR: Remove unneeded boot_params argument
x86/boot: Move compressed kernel to the end of the decompression buffer x86/boot: Calculate decompression size during boot not build
x86/boot: Fix "run_size" calculation
x86/KASLR: Clean up unused code from old 'run_size' and rename it to 'kernel_total_size' x86/boot: Correctly bounds-check relocations
x86/KASLR: Consolidate mem_avoid[] entries
x86/boot: Split out kernel_ident_mapping_init()
arch/x86/Kconfig | 72 ++---
arch/x86/Makefile | 3 +-
arch/x86/boot/Makefile | 13 +-
arch/x86/boot/compressed/Makefile | 23 +-
arch/x86/boot/compressed/aslr.c | 339 ----------------------
arch/x86/boot/compressed/cmdline.c | 4 +-
arch/x86/boot/compressed/error.c | 22 ++
arch/x86/boot/compressed/error.h | 7 +
arch/x86/boot/compressed/head_32.S | 22 +-
arch/x86/boot/compressed/head_64.S | 19 +-
arch/x86/boot/compressed/kaslr.c | 510 +++++++++++++++++++++++++++++++++
arch/x86/boot/compressed/misc.c | 188 ++++--------
arch/x86/boot/compressed/misc.h | 27 +-
arch/x86/boot/compressed/mkpiggy.c | 34 +--
arch/x86/boot/compressed/pagetable.c | 129 +++++++++
arch/x86/boot/compressed/string.c | 37 ++-
arch/x86/boot/compressed/vmlinux.lds.S | 1 +
arch/x86/boot/early_serial_console.c | 4 +
arch/x86/boot/header.S | 109 ++++++-
arch/x86/include/asm/boot.h | 39 ++-
arch/x86/include/asm/page.h | 5 +
arch/x86/include/asm/page_64_types.h | 8 +-
arch/x86/include/asm/paravirt.h | 11 -
arch/x86/include/asm/paravirt_types.h | 6 -
arch/x86/include/asm/processor.h | 2 -
arch/x86/include/asm/x86_init.h | 50 ++++
arch/x86/include/uapi/asm/bootparam.h | 41 ++-
arch/x86/kernel/Makefile | 6 +-
arch/x86/kernel/acpi/boot.c | 9 +
arch/x86/kernel/apm_32.c | 2 +-
arch/x86/kernel/asm-offsets.c | 1 +
arch/x86/kernel/cpu/intel.c | 2 +-
arch/x86/kernel/{head.c => ebda.c} | 2 +-
arch/x86/kernel/head32.c | 2 +
arch/x86/kernel/head64.c | 1 +
arch/x86/kernel/kvm.c | 8 -
arch/x86/kernel/paravirt.c | 1 -
arch/x86/kernel/platform-quirks.c | 35 +++
arch/x86/kernel/rtc.c | 18 +-
arch/x86/kernel/tboot.c | 6 -
arch/x86/kernel/vmlinux.lds.S | 2 +-
arch/x86/lguest/boot.c | 3 -
arch/x86/mm/ident_map.c | 79 +++++
arch/x86/mm/init_32.c | 3 -
arch/x86/mm/init_64.c | 74 +----
arch/x86/tools/calc_run_size.sh | 42 ---
arch/x86/xen/enlighten.c | 12 +-
drivers/pnp/pnpbios/core.c | 3 +-
include/linux/pnp.h | 2 +
tools/lguest/lguest.c | 10 +-
50 files changed, 1262 insertions(+), 786 deletions(-)
delete mode 100644 arch/x86/boot/compressed/aslr.c
create mode 100644 arch/x86/boot/compressed/error.c
create mode 100644 arch/x86/boot/compressed/error.h
create mode 100644 arch/x86/boot/compressed/kaslr.c
create mode 100644 arch/x86/boot/compressed/pagetable.c
rename arch/x86/kernel/{head.c => ebda.c} (98%)
create mode 100644 arch/x86/kernel/platform-quirks.c
create mode 100644 arch/x86/mm/ident_map.c
delete mode 100644 arch/x86/tools/calc_run_size.sharch/x86/Kconfig +28 -44
@@ -1932,54 +1932,38 @@ config RELOCATABLE (CONFIG_PHYSICAL_START) is used as the minimum location. config RANDOMIZE_BASE - bool "Randomize the address of the kernel image" + bool "Randomize the address of the kernel image (KASLR)" depends on RELOCATABLE default n ---help--- - Randomizes the physical and virtual address at which the - kernel image is decompressed, as a security feature that - deters exploit attempts relying on knowledge of the location - of kernel internals. + In support of Kernel Address Space Layout Randomization (KASLR), + this randomizes the physical address at which the kernel image + is decompressed and the virtual address where the kernel + image is mapped, as a security feature that deters exploit + attempts relying on knowledge of the location of kernel + code internals. + + The kernel physical and virtual address can be randomized + from 16MB up to 1GB on 64-bit and 512MB on 32-bit. (Note that + using RANDOMIZE_BASE reduces the memory space available to + kernel modules from 1.5GB to 1GB.) + + Entropy is generated using the RDRAND instruction if it is + supported. If RDTSC is supported, its value is mixed into + the entropy pool as well. If neither RDRAND nor RDTSC are + supported, then entropy is read from the i8254 timer. + + Since the kernel is built using 2GB addressing, and + PHYSICAL_ALIGN must be at a minimum of 2MB, only 10 bits of + entropy is theoretically possible. Currently, with the + default value for PHYSICAL_ALIGN and due to page table + layouts, 64-bit uses 9 bits of entropy and 32-bit uses 8 bits. + + If CONFIG_HIBERNATE is also enabled, KASLR is disabled at boot + time. To enable it, boot with "kaslr" on the kernel command + line (which will also disable hibernation). - Entropy is generated using the RDRAND instruction if it is - supported. If RDTSC is supported, it is used as well. If - neither RDRAND nor RDTSC are supported, then randomness is - read from the i8254 timer. - - The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET, - and aligned according to PHYSICAL_ALIGN. Since the kernel is - built using 2GiB addressing, and PHYSICAL_ALGIN must be at a - minimum of 2MiB, only 10 bits of entropy is theoretically - possible. At best, due to page table layouts, 64-bit can use - 9 bits of entropy and 32-bit uses 8 bits. - - If unsure, say N. - -config RANDOMIZE_BASE_MAX_OFFSET - hex "Maximum kASLR offset allowed" if EXPERT - depends on RANDOMIZE_BASE - range 0x0 0x20000000 if X86_32 - default "0x20000000" if X86_32 - range 0x0 0x40000000 if X86_64 - default "0x40000000" if X86_64 - ---help--- - The lesser of RANDOMIZE_BASE_MAX_OFFSET and available physical - memory is used to determine the maximal offset in bytes that will - be applied to the kernel when kernel Address Space Layout - Randomization (kASLR) is active. This must be a multiple of - PHYSICAL_ALIGN. - - On 32-bit this is limited to 512MiB by page table layouts. The - default is 512MiB. - - On 64-bit this is limited by how the kernel fixmap page table is - positioned, so this cannot be larger than 1GiB currently. Without - RANDOMIZE_BASE, there is a 512MiB to 1.5GiB split between kernel - and modules. When RANDOMIZE_BASE_MAX_OFFSET is above 512MiB, the - modules area will shrink to compensate, up to the current maximum - 1GiB to 1GiB split. The default is 1GiB. - - If unsure, leave at the default value. + If unsure, say N. # Relocation on x86 needs some additional build support config X86_NEED_RELOCS
arch/x86/Makefile +2 -1
@@ -208,7 +208,8 @@ endif head-y := arch/x86/kernel/head_$(BITS).o head-y += arch/x86/kernel/head$(BITS).o -head-y += arch/x86/kernel/head.o +head-y += arch/x86/kernel/ebda.o +head-y += arch/x86/kernel/platform-quirks.o libs-y += arch/x86/lib/
arch/x86/boot/Makefile +2 -11
@@ -86,16 +86,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) -sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|_end\)$$/\#define VO_\2 0x\1/p' - -quiet_cmd_voffset = VOFFSET $@ - cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@ - -targets += voffset.h -$(obj)/voffset.h: vmlinux FORCE - $(call if_changed,voffset) - -sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' +sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p' quiet_cmd_zoffset = ZOFFSET $@ cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
@@ -106,7 +97,7 @@ $(obj)/zoffset.h: $(obj)/compressed/vmlinux FORCE AFLAGS_header.o += -I$(obj) -$(obj)/header.o: $(obj)/voffset.h $(obj)/zoffset.h +$(obj)/header.o: $(obj)/zoffset.h LDFLAGS_setup.elf := -T $(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
arch/x86/boot/compressed/Makefile +18 -5
@@ -57,12 +57,27 @@ LDFLAGS_vmlinux := -T hostprogs-y := mkpiggy HOST_EXTRACFLAGS += -I$(srctree)/tools/include +sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p' + +quiet_cmd_voffset = VOFFSET $@ + cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@ + +targets += ../voffset.h + +$(obj)/../voffset.h: vmlinux FORCE + $(call if_changed,voffset) + +$(obj)/misc.o: $(obj)/../voffset.h + vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ - $(obj)/string.o $(obj)/cmdline.o \ + $(obj)/string.o $(obj)/cmdline.o $(obj)/error.o \ $(obj)/piggy.o $(obj)/cpuflags.o vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $(obj)/early_serial_console.o -vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/aslr.o +vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o +ifdef CONFIG_X86_64 + vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/pagetable.o +endif $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone
@@ -109,10 +124,8 @@ suffix-$(CONFIG_KERNEL_XZ) := xz suffix-$(CONFIG_KERNEL_LZO) := lzo suffix-$(CONFIG_KERNEL_LZ4) := lz4 -RUN_SIZE = $(shell $(OBJDUMP) -h vmlinux | \ - $(CONFIG_SHELL) $(srctree)/arch/x86/tools/calc_run_size.sh) quiet_cmd_mkpiggy = MKPIGGY $@ - cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false ) + cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false ) targets += piggy.S $(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE
arch/x86/boot/compressed/aslr.c deleted +0 -339
339 lines not on this page · raw message
arch/x86/boot/compressed/cmdline.c +2 -2
@@ -15,9 +15,9 @@ static inline char rdfs8(addr_t addr)#include "../cmdline.c" static unsigned long get_cmd_line_ptr (void ) { -unsigned long cmd_line_ptr = real_mode->hdr.cmd_line_ptr; +unsigned long cmd_line_ptr = boot_params->hdr.cmd_line_ptr; - cmd_line_ptr |= (u64 )real_mode->ext_cmd_line_ptr <<32 ; + cmd_line_ptr |= (u64 )boot_params->ext_cmd_line_ptr <<32 ;return cmd_line_ptr; }
arch/x86/boot/compressed/error.c new file +22 -0
@@ -0,0 +1,22 @@ +/* +* Callers outside of misc.c need access to the error reporting routines, +* but the *_putstr() functions need to stay in misc.c because of how +* memcpy() and memmove() are defined for the compressed boot environment. +*/ +#include "misc.h" + +void warn (char *m) +{ +error_putstr ("\n\n" ); +error_putstr (m); +error_putstr ("\n\n" ); +} + +void error (char *m) +{ +warn (m); +error_putstr (" -- System halted" ); + +while (1 ) + asm("hlt" ); +}
arch/x86/boot/compressed/error.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef BOOT_COMPRESSED_ERROR_H +#define BOOT_COMPRESSED_ERROR_H + +void warn (char *m); +void error (char *m); + +#endif /* BOOT_COMPRESSED_ERROR_H */
arch/x86/boot/compressed/head_32.S +14 -8
@@ -176,7 +176,9 @@ ENTRY(efi32_stub_entry) 1: /* Target address to relocate to for decompression */ - addl $z_extract_offset, %ebx + movl BP_init_size(%esi), %eax + subl $_end, %eax + addl %eax, %ebx /* Set up the stack */ leal boot_stack_end(%ebx), %esp
@@ -233,24 +235,28 @@ ENDPROC(startup_32) 2: /* - * Do the decompression, and jump to the new kernel.. + * Do the extraction, and jump to the new kernel.. */ - /* push arguments for decompress_kernel: */ - pushl $z_run_size /* size of kernel with .bss and .brk */ + /* push arguments for extract_kernel: */ pushl $z_output_len /* decompressed length, end of relocs */ - leal z_extract_offset_negative(%ebx), %ebp + + movl BP_init_size(%esi), %eax + subl $_end, %eax + movl %ebx, %ebp + subl %eax, %ebp pushl %ebp /* output address */ + pushl $z_input_len /* input_len */ leal input_data(%ebx), %eax pushl %eax /* input_data */ leal boot_heap(%ebx), %eax pushl %eax /* heap area */ pushl %esi /* real mode pointer */ - call decompress_kernel /* returns kernel location in %eax */ - addl $28, %esp + call extract_kernel /* returns kernel location in %eax */ + addl $24, %esp /* - * Jump to the decompressed kernel. + * Jump to the extracted kernel. */ xorl %ebx, %ebx jmp *%eax
arch/x86/boot/compressed/head_64.S +10 -9
@@ -110,7 +110,9 @@ ENTRY(startup_32) 1: /* Target address to relocate to for decompression */ - addl $z_extract_offset, %ebx + movl BP_init_size(%esi), %eax + subl $_end, %eax + addl %eax, %ebx /* * Prepare for entering 64 bit mode
@@ -132,7 +134,7 @@ ENTRY(startup_32) /* Initialize Page tables to 0 */ leal pgtable(%ebx), %edi xorl %eax, %eax - movl $((4096*6)/4), %ecx + movl $(BOOT_INIT_PGT_SIZE/4), %ecx rep stosl /* Build Level 4 */
@@ -338,7 +340,9 @@ ENTRY(efi_pe_entry) 1: /* Target address to relocate to for decompression */ - leaq z_extract_offset(%rbp), %rbx + movl BP_init_size(%rsi), %ebx + subl $_end, %ebx + addq %rbp, %rbx /* Set up the stack */ leaq boot_stack_end(%rbx), %rsp
@@ -408,19 +412,16 @@ ENDPROC(efi64_stub_entry) 2: /* - * Do the decompression, and jump to the new kernel.. + * Do the extraction, and jump to the new kernel.. */ pushq %rsi /* Save the real mode argument */ - movq $z_run_size, %r9 /* size of kernel with .bss and .brk */ - pushq %r9 movq %rsi, %rdi /* real mode address */ leaq boot_heap(%rip), %rsi /* malloc area for uncompression */ leaq input_data(%rip), %rdx /* input_data */ movl $z_input_len, %ecx /* input_len */ movq %rbp, %r8 /* output target address */ movq $z_output_len, %r9 /* decompressed length, end of relocs */ - call decompress_kernel /* returns kernel location in %rax */ - popq %r9 + call extract_kernel /* returns kernel location in %rax */ popq %rsi /*
@@ -485,4 +486,4 @@ ENDPROC(efi64_stub_entry) .section ".pgtable","a",@nobits .balign 4096 pgtable: - .fill 6*4096, 1, 0 + .fill BOOT_PGT_SIZE, 1, 0
arch/x86/boot/compressed/kaslr.c new file +510 -0
510 lines not on this page · raw message
arch/x86/boot/compressed/misc.c +63 -125
303 lines not on this page · raw message
arch/x86/boot/compressed/misc.h +18 -9
@@ -32,7 +32,7 @@/* misc.c */ extern memptr free_mem_ptr;extern memptr free_mem_end_ptr; -extern struct boot_params *real_mode;/* Pointer to real-mode data */ +extern struct boot_params *boot_params;void __putstr (const char *s);void __puthex (unsigned long value);#define error_putstr (__x) __putstr(__x)
@@ -66,26 +66,35 @@ int cmdline_find_option_bool(const char *option);#if CONFIG_RANDOMIZE_BASE -/* aslr.c */ -unsigned char *choose_kernel_location (struct boot_params *boot_params, -unsigned char *input, +/* kaslr.c */ +unsigned char *choose_random_location (unsigned long input_ptr,unsigned long input_size, -unsigned char *output, +unsigned long output_ptr,unsigned long output_size);/* cpuflags.c */ bool has_cpuflag (int flag);#else static inline -unsigned char *choose_kernel_location (struct boot_params *boot_params, -unsigned char *input, +unsigned char *choose_random_location (unsigned long input_ptr,unsigned long input_size, -unsigned char *output, +unsigned long output_ptr,unsigned long output_size) { -return output; +return (unsigned char *)output_ptr; }#endif +#ifdef CONFIG_X86_64 +void add_identity_map (unsigned long start,unsigned long size); +void finalize_identity_maps (void ); +extern unsigned char _pgtable[]; +#else +static inline void add_identity_map (unsigned long start,unsigned long size) +{ } +static inline void finalize_identity_maps (void ) +{ } +#endif +#ifdef CONFIG_EARLY_PRINTK /* early_serial_console.c */ extern int early_serial_base;
arch/x86/boot/compressed/mkpiggy.c +6 -28
@@ -18,11 +18,10 @@* * H. Peter Anvin <[email protected]> * -* ----------------------------------------------------------------------- */ - -/* -* Compute the desired load offset from a compressed program; outputs -* a small assembly wrapper with the appropriate symbols defined. +* ----------------------------------------------------------------------- +* +* Outputs a small assembly wrapper with the appropriate symbols defined. +* */ #include <stdlib.h>
@@ -35,14 +34,11 @@ int main(int argc, char *argv[]) {uint32_t olen;long ilen; -unsigned long offs; -unsigned long run_size;FILE *f =NULL ;int retval =1 ; -if (argc <3 ) { -fprintf (stderr,"Usage: %s compressed_file run_size\n" , - argv[0 ]); +if (argc <2 ) { +fprintf (stderr,"Usage: %s compressed_file\n" , argv[0 ]); goto bail; }
@@ -67,29 +63,11 @@ int main(int argc, char *argv[]) ilen =ftell (f); olen =get_unaligned_le32 (&olen); -/* -* Now we have the input (compressed) and output (uncompressed) -* sizes, compute the necessary decompression offset... -*/ - - offs = (olen > ilen) ? olen - ilen :0 ; - offs += olen >>12 ;/* Add 8 bytes for each 32K block */ - offs +=64 *1024 +128 ;/* Add 64K + 128 bytes slack */ - offs = (offs+4095 ) & ~4095 ;/* Round to a 4K boundary */ - run_size =atoi (argv[2 ]); -printf (".section \".rodata..compressed\",\"a\",@progbits\n" );printf (".globl z_input_len\n" );printf ("z_input_len = %lu\n" , ilen);printf (".globl z_output_len\n" );printf ("z_output_len = %lu\n" , (unsigned long )olen); -printf (".globl z_extract_offset\n" ); -printf ("z_extract_offset = 0x%lx\n" , offs); -/* z_extract_offset_negative allows simplification of head_32.S */ -printf (".globl z_extract_offset_negative\n" ); -printf ("z_extract_offset_negative = -0x%lx\n" , offs); -printf (".globl z_run_size\n" ); -printf ("z_run_size = %lu\n" , run_size);printf (".globl input_data, input_data_end\n" );printf ("input_data:\n" );
arch/x86/boot/compressed/pagetable.c new file +129 -0
129 lines not on this page · raw message
arch/x86/boot/compressed/string.c +35 -2
@@ -1,7 +1,16 @@ +/* +* This provides an optimized implementation of memcpy, and a simplified +* implementation of memset and memmove. These are used here because the +* standard kernel runtime versions are not yet available and we don't +* trust the gcc built-in implementations as they may do unexpected things +* (e.g. FPU ops) in the minimal decompression stub execution environment. +*/ +#include "error.h" +#include "../string.c" #ifdef CONFIG_X86_32 -void *memcpy (void *dest,const void *src,size_t n) +static void *__memcpy (void *dest,const void *src,size_t n) {int d0, d1, d2; asm volatile(
@@ -15,7 +24,7 @@ void *memcpy(void *dest, const void *src, size_t n)return dest; }#else -void *memcpy (void *dest,const void *src,size_t n) +static void *__memcpy (void *dest,const void *src,size_t n) {long d0, d1, d2; asm volatile(
@@ -39,3 +48,27 @@ void *memset(void *s, int c, size_t n) ss[i] = c;return s; } + +void *memmove (void *dest,const void *src,size_t n) +{ +unsigned char *d = dest; +const unsigned char *s = src; + +if (d <= s || d - s >= n) +return __memcpy (dest, src, n); + +while (n-- >0 ) + d[n] = s[n]; + +return dest; +} + +/* Detect and warn about potential overlaps, but handle them with memmove. */ +void *memcpy (void *dest,const void *src,size_t n) +{ +if (dest > src && dest - src < n) { +warn ("Avoiding potentially unsafe overlapping memcpy()!" ); +return memmove (dest, src, n); + } +return __memcpy (dest, src, n); +}
arch/x86/boot/compressed/vmlinux.lds.S +1 -0
@@ -70,5 +70,6 @@ SECTIONS _epgtable = . ; } #endif + . = ALIGN(PAGE_SIZE); /* keep ZO size page aligned */ _end = .; }
arch/x86/boot/early_serial_console.c +4 -0
@@ -1,3 +1,7 @@ +/* +* Serial port routines for use during early boot reporting. This code is +* included from both the compressed kernel and the regular kernel. +*/ #include "boot.h" #define DEFAULT_SERIAL_PORT 0x3f8/* ttyS0 */
arch/x86/boot/header.S +106 -3
119 lines not on this page · raw message
arch/x86/include/asm/boot.h +28 -11
@@ -12,29 +12,46 @@/* Minimum kernel alignment, as a power of two */ #ifdef CONFIG_X86_64 -#define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT +# define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT#else -#define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT + THREAD_SIZE_ORDER) +# define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT + THREAD_SIZE_ORDER)#endif #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2)#if (CONFIG_PHYSICAL_ALIGN & (CONFIG_PHYSICAL_ALIGN -1 )) || \ (CONFIG_PHYSICAL_ALIGN <MIN_KERNEL_ALIGN ) -#error "Invalid value for CONFIG_PHYSICAL_ALIGN" +# error "Invalid value for CONFIG_PHYSICAL_ALIGN"#endif #ifdef CONFIG_KERNEL_BZIP2 -#define BOOT_HEAP_SIZE 0x400000 +# define BOOT_HEAP_SIZE 0x400000#else /* !CONFIG_KERNEL_BZIP2 */ - -#define BOOT_HEAP_SIZE 0x10000 - -#endif /* !CONFIG_KERNEL_BZIP2 */ +# define BOOT_HEAP_SIZE 0x10000 +#endif #ifdef CONFIG_X86_64 -#define BOOT_STACK_SIZE 0x4000 -#else -#define BOOT_STACK_SIZE 0x1000 +# define BOOT_STACK_SIZE 0x4000 + +# define BOOT_INIT_PGT_SIZE (6*4096) +# ifdef CONFIG_RANDOMIZE_BASE +/* +* Assuming all cross the 512GB boundary: +* 1 page for level4 +* (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel +* 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). +* Total is 19 pages. +*/ +# ifdef CONFIG_X86_VERBOSE_BOOTUP +# define BOOT_PGT_SIZE (19*4096) +# else /* !CONFIG_X86_VERBOSE_BOOTUP */ +# define BOOT_PGT_SIZE (17*4096) +# endif +# else /* !CONFIG_RANDOMIZE_BASE */ +# define BOOT_PGT_SIZE BOOT_INIT_PGT_SIZE +# endif + +#else /* !CONFIG_X86_64 */ +# define BOOT_STACK_SIZE 0x1000#endif #endif /* _ASM_X86_BOOT_H */
arch/x86/include/asm/page.h +5 -0
@@ -37,7 +37,10 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE +#ifndef __pa#define __pa (x) __phys_addr((unsigned long)(x)) +#endif +#define __pa_nodebug (x) __phys_addr_nodebug((unsigned long)(x))/* __pa_symbol should be used for C visible symbols. This seems to be the official gcc blessed way to do such arithmetic. */
@@ -51,7 +54,9 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr,#define __pa_symbol (x) \ __phys_addr_symbol(__phys_reloc_hide((unsigned long)(x))) +#ifndef __va#define __va (x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#endif #define __boot_va (x) __va(x)#define __boot_pa (x) __pa(x)
arch/x86/include/asm/page_64_types.h +3 -5
@@ -47,12 +47,10 @@* are fully set up. If kernel ASLR is configured, it can extend the * kernel page table mapping, reducing the size of the modules area. */ -#define KERNEL_IMAGE_SIZE_DEFAULT (512 * 1024 * 1024) -#if defined(CONFIG_RANDOMIZE_BASE ) && \ -CONFIG_RANDOMIZE_BASE_MAX_OFFSET >KERNEL_IMAGE_SIZE_DEFAULT -#define KERNEL_IMAGE_SIZE CONFIG_RANDOMIZE_BASE_MAX_OFFSET +#if defined(CONFIG_RANDOMIZE_BASE ) +#define KERNEL_IMAGE_SIZE (1024 * 1024 * 1024)#else -#define KERNEL_IMAGE_SIZE KERNEL_IMAGE_SIZE_DEFAULT +#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024)#endif #endif /* _ASM_X86_PAGE_64_DEFS_H */
arch/x86/include/asm/paravirt.h +0 -11
@@ -15,17 +15,6 @@#include <linux/cpumask.h> #include <asm/frame.h> -static inline int paravirt_enabled (void ) -{ -return pv_info.paravirt_enabled; -} - -static inline int paravirt_has_feature (unsigned int feature) -{ -WARN_ON_ONCE (!pv_info.paravirt_enabled); -return (pv_info.features & feature); -} -static inline void load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
arch/x86/include/asm/paravirt_types.h +0 -6
@@ -69,15 +69,9 @@ struct pv_info {u16 extra_user_64bit_cs;/* __USER_CS if none */ #endif -int paravirt_enabled; -unsigned int features;/* valid only if paravirt_enabled is set */ const char *name; }; -#define paravirt_has (x) paravirt_has_feature(PV_SUPPORTED_##x) -/* Supported features */ -#define PV_SUPPORTED_RTC (1<<0) -struct pv_init_ops {/* * Patch may replace one of the defined code sequences with
arch/x86/include/asm/processor.h +0 -2
@@ -473,8 +473,6 @@ static inline unsigned long current_top_of_stack(void)#include <asm/paravirt.h> #else #define __cpuid native_cpuid -#define paravirt_enabled () 0 -#define paravirt_has (x) 0static inline void load_sp0 (struct tss_struct *tss,struct thread_struct *thread)
arch/x86/include/asm/x86_init.h +50 -0
74 lines not on this page · raw message
arch/x86/include/uapi/asm/bootparam.h +40 -1
47 lines not on this page · raw message
arch/x86/kernel/Makefile +5 -1
@@ -2,7 +2,11 @@ # Makefile for the linux kernel. # -extra-y := head_$(BITS).o head$(BITS).o head.o vmlinux.lds +extra-y := head_$(BITS).o +extra-y += head$(BITS).o +extra-y += ebda.o +extra-y += platform-quirks.o +extra-y += vmlinux.lds CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
arch/x86/kernel/acpi/boot.c +9 -0
@@ -913,6 +913,15 @@ late_initcall(hpet_insert_resource);static int __init acpi_parse_fadt (struct acpi_table_header *table) { +if (!(acpi_gbl_FADT.boot_flags &ACPI_FADT_LEGACY_DEVICES )) { +pr_debug ("ACPI: no legacy devices present\n" ); + x86_platform.legacy.devices.pnpbios =0 ; + } + +if (acpi_gbl_FADT.boot_flags &ACPI_FADT_NO_CMOS_RTC ) { +pr_debug ("ACPI: not registering RTC platform device\n" ); + x86_platform.legacy.rtc =0 ; + }#ifdef CONFIG_X86_PM_TIMER /* detect the location of the ACPI PM Timer */
arch/x86/kernel/apm_32.c +1 -1
@@ -2267,7 +2267,7 @@ static int __init apm_init(void)dmi_check_system (apm_dmi_table); -if (apm_info.bios.version ==0 ||paravirt_enabled () ||machine_is_olpc ()) { +if (apm_info.bios.version ==0 ||machine_is_olpc ()) {printk (KERN_INFO "apm: BIOS not found.\n" );return -ENODEV ; }
arch/x86/kernel/asm-offsets.c +1 -0
@@ -80,6 +80,7 @@ void common(void) {OFFSET (BP_hardware_subarch, boot_params, hdr.hardware_subarch);OFFSET (BP_version, boot_params, hdr.version);OFFSET (BP_kernel_alignment, boot_params, hdr.kernel_alignment); +OFFSET (BP_init_size, boot_params, hdr.init_size);OFFSET (BP_pref_address, boot_params, hdr.pref_address);OFFSET (BP_code32_start, boot_params, hdr.code32_start);
arch/x86/kernel/cpu/intel.c +1 -1
@@ -233,7 +233,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)* The Quark is also family 5, but does not have the same bug. */ clear_cpu_bug (c,X86_BUG_F00F ); -if (!paravirt_enabled () && c->x86 ==5 && c->x86_model <9 ) { +if (c->x86 ==5 && c->x86_model <9 ) {static int f00f_workaround_enabled;set_cpu_bug (c,X86_BUG_F00F );
arch/x86/kernel/ebda.c renamed from arch/x86/kernel/head.c +1 -1
@@ -38,7 +38,7 @@ void __init reserve_ebda_region(void)* that the paravirt case can handle memory setup * correctly, without our help. */ -if (paravirt_enabled ()) +if (!x86_platform.legacy.ebda_search)return ;/* end of low (conventional) memory */
arch/x86/kernel/head32.c +2 -0
@@ -34,6 +34,8 @@ asmlinkage __visible void __init i386_start_kernel(void)cr4_init_shadow ();sanitize_boot_params (&boot_params); +x86_early_init_platform_quirks (); +/* Call the subarch specific early setup function */ switch (boot_params.hdr.hardware_subarch) {case X86_SUBARCH_INTEL_MID :
arch/x86/kernel/head64.c +1 -0
@@ -182,6 +182,7 @@ void __init x86_64_start_reservations(char *real_mode_data)if (!boot_params.hdr.version)copy_bootdata (__va (real_mode_data)); +x86_early_init_platform_quirks ();reserve_ebda_region ();switch (boot_params.hdr.hardware_subarch) {
arch/x86/kernel/kvm.c +0 -8
@@ -285,14 +285,6 @@ static void __init paravirt_ops_setup(void) { pv_info.name ="KVM" ; -/* -* KVM isn't paravirt in the sense of paravirt_enabled. A KVM -* guest kernel works like a bare metal kernel with additional -* features, and paravirt_enabled is about features that are -* missing. -*/ - pv_info.paravirt_enabled =0 ; -if (kvm_para_has_feature (KVM_FEATURE_NOP_IO_DELAY )) pv_cpu_ops.io_delay = kvm_io_delay;
arch/x86/kernel/paravirt.c +0 -1
@@ -294,7 +294,6 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void)struct pv_info pv_info = { .name ="bare hardware" , - .paravirt_enabled =0 , .kernel_rpl =0 , .shared_kernel_pmd =1 ,/* Only used when CONFIG_X86_PAE is set */
arch/x86/kernel/platform-quirks.c new file +35 -0
@@ -0,0 +1,35 @@ +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/setup.h> +#include <asm/bios_ebda.h> + +void __init x86_early_init_platform_quirks (void ) +{ + x86_platform.legacy.rtc =1 ; + x86_platform.legacy.ebda_search =0 ; + x86_platform.legacy.devices.pnpbios =1 ; + +switch (boot_params.hdr.hardware_subarch) { +case X86_SUBARCH_PC : + x86_platform.legacy.ebda_search =1 ; +break ; +case X86_SUBARCH_XEN : +case X86_SUBARCH_LGUEST : +case X86_SUBARCH_INTEL_MID : +case X86_SUBARCH_CE4100 : + x86_platform.legacy.devices.pnpbios =0 ; + x86_platform.legacy.rtc =0 ; +break ; + } + +if (x86_platform.set_legacy_features) + x86_platform.set_legacy_features (); +} + +#if defined(CONFIG_PNPBIOS ) +bool __init arch_pnpbios_disabled (void ) +{ +return x86_platform.legacy.devices.pnpbios ==0 ; +} +#endif
arch/x86/kernel/rtc.c +2 -16
@@ -14,6 +14,7 @@#include <asm/time.h> #include <asm/intel-mid.h> #include <asm/rtc.h> +#include <asm/setup.h> #ifdef CONFIG_X86_32 /*
@@ -185,22 +186,7 @@ static __init int add_rtc_cmos(void) } }#endif -if (of_have_populated_dt ()) -return 0 ; - -/* Intel MID platforms don't have ioport rtc */ -if (intel_mid_identify_cpu ()) -return -ENODEV ; - -#ifdef CONFIG_ACPI -if (acpi_gbl_FADT.boot_flags &ACPI_FADT_NO_CMOS_RTC ) { -/* This warning can likely go away again in a year or two. */ -pr_info ("ACPI: not registering RTC platform device\n" ); -return -ENODEV ; - } -#endif - -if (paravirt_enabled () && !paravirt_has (RTC )) +if (!x86_platform.legacy.rtc)return -ENODEV ;platform_device_register (&rtc_device);
arch/x86/kernel/tboot.c +0 -6
@@ -74,12 +74,6 @@ void __init tboot_probe(void)return ; } -/* only a natively booted kernel should be using TXT */ -if (paravirt_enabled ()) { -pr_warning ("non-0 tboot_addr but pv_ops is enabled\n" ); -return ; - } -/* Map and check for tboot UUID. */ set_fixmap (FIX_TBOOT_BASE , boot_params.tboot_addr); tboot = (struct tboot *)fix_to_virt (FIX_TBOOT_BASE );
arch/x86/kernel/vmlinux.lds.S +1 -1
@@ -334,7 +334,7 @@ SECTIONS __brk_limit = .; } - . = ALIGN(PAGE_SIZE); + . = ALIGN(PAGE_SIZE); /* keep VO_INIT_SIZE page aligned */ _end = .; STABS_DEBUG
arch/x86/lguest/boot.c +0 -3
@@ -1408,13 +1408,10 @@ __init void lguest_init(void) {/* We're under lguest. */ pv_info.name ="lguest" ; -/* Paravirt is enabled. */ - pv_info.paravirt_enabled =1 ;/* We're running at privilege level 1, not 0 as normal. */ pv_info.kernel_rpl =1 ;/* Everyone except Xen runs with this set. */ pv_info.shared_kernel_pmd =1 ; - pv_info.features =0 ;/* * We set up all the lguest overrides for sensitive operations. These
arch/x86/mm/ident_map.c new file +79 -0
79 lines not on this page · raw message
arch/x86/mm/init_32.c +0 -3
@@ -804,9 +804,6 @@ void __init mem_init(void)BUILD_BUG_ON (VMALLOC_START >=VMALLOC_END );#undef high_memory#undef __FIXADDR_TOP -#ifdef CONFIG_RANDOMIZE_BASE -BUILD_BUG_ON (CONFIG_RANDOMIZE_BASE_MAX_OFFSET >KERNEL_IMAGE_SIZE ); -#endif #ifdef CONFIG_HIGHMEM BUG_ON (PKMAP_BASE +LAST_PKMAP *PAGE_SIZE >FIXADDR_START );
arch/x86/mm/init_64.c +1 -73
80 lines not on this page · raw message
arch/x86/tools/calc_run_size.sh deleted +0 -42
42 lines not on this page · raw message
arch/x86/xen/enlighten.c +8 -4
@@ -1187,13 +1187,11 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf, }static const struct pv_info xen_info__initconst = { - .paravirt_enabled =1 , .shared_kernel_pmd =0 , #ifdef CONFIG_X86_64 .extra_user_64bit_cs =FLAT_USER_CS64 , #endif - .features =0 , .name ="Xen" , };
@@ -1506,6 +1504,11 @@ static void __init xen_pvh_early_guest_init(void) }#endif /* CONFIG_XEN_PVH */ +static void __init xen_dom0_set_legacy_features (void ) +{ + x86_platform.legacy.rtc =1 ; +} +/* First C function to be called on Xen boot */ asmlinkage __visible void __init xen_start_kernel(void) {
@@ -1527,8 +1530,6 @@ asmlinkage __visible void __init xen_start_kernel(void)/* Install Xen paravirt ops */ pv_info = xen_info; -if (xen_initial_domain ()) - pv_info.features |=PV_SUPPORTED_RTC ; pv_init_ops = xen_init_ops;if (!xen_pvh_domain ()) { pv_cpu_ops = xen_cpu_ops;
@@ -1670,6 +1671,7 @@ asmlinkage __visible void __init xen_start_kernel(void) boot_params.hdr.ramdisk_image = initrd_start; boot_params.hdr.ramdisk_size = xen_start_info->mod_len; boot_params.hdr.cmd_line_ptr =__pa (xen_start_info->cmd_line); + boot_params.hdr.hardware_subarch =X86_SUBARCH_XEN ;if (!xen_initial_domain ()) {add_preferred_console ("xenboot" ,0 ,NULL );
@@ -1687,6 +1689,8 @@ asmlinkage __visible void __init xen_start_kernel(void) .u.firmware_info.type = XEN_FW_KBD_SHIFT_FLAGS, }; + x86_platform.set_legacy_features = + xen_dom0_set_legacy_features;xen_init_vga (info, xen_start_info->console.dom0.info_size); xen_start_info->console.domU.mfn =0 ; xen_start_info->console.domU.evtchn =0 ;
drivers/pnp/pnpbios/core.c +2 -1
@@ -521,10 +521,11 @@ static int __init pnpbios_init(void)int ret;if (pnpbios_disabled ||dmi_check_system (pnpbios_dmi_table) || -paravirt_enabled ()) { +arch_pnpbios_disabled ()) {printk (KERN_INFO "PnPBIOS: Disabled\n" );return -ENODEV ; } +#ifdef CONFIG_PNPACPI if (!acpi_disabled && !pnpacpi_disabled) { pnpbios_disabled =1 ;
include/linux/pnp.h +2 -0
@@ -337,9 +337,11 @@ extern struct mutex pnp_res_mutex;#ifdef CONFIG_PNPBIOS extern struct pnp_protocol pnpbios_protocol; +extern bool arch_pnpbios_disabled (void );#define pnp_device_is_pnpbios (dev) ((dev)->protocol == (&pnpbios_protocol))#else #define pnp_device_is_pnpbios (dev) 0 +#define arch_pnpbios_disabled () false#endif #ifdef CONFIG_PNPACPI
tools/lguest/lguest.c +8 -2
@@ -3351,12 +3351,18 @@ int main(int argc, char *argv[])/* Boot protocol version: 2.07 supports the fields for lguest. */ boot->hdr.version =0x207 ; -/* The hardware_subarch value of "1" tells the Guest it's an lguest. */ - boot->hdr.hardware_subarch =1 ; +/* X86_SUBARCH_LGUEST tells the Guest it's an lguest. */ + boot->hdr.hardware_subarch =X86_SUBARCH_LGUEST ;/* Tell the entry path not to try to reload segment registers. */ boot->hdr.loadflags |=KEEP_SEGMENTS ; +/* We don't support tboot: */ + boot->tboot_addr =0 ; + +/* Ensure this is 0 to prevent APM from loading: */ + boot->apm_bios_info.version =0 ; +/* We tell the kernel to initialize the Guest. */ tell_kernel (start);