2011-02-09 16:24:34 +08:00
|
|
|
/*
|
|
|
|
* Generate definitions needed by assembly language modules.
|
|
|
|
* This code generates raw asm output which is post-processed to extract
|
|
|
|
* and format the required data.
|
|
|
|
*/
|
|
|
|
#define COMPILE_OFFSETS
|
|
|
|
|
|
|
|
#include <linux/crypto.h>
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/stddef.h>
|
|
|
|
#include <linux/hardirq.h>
|
|
|
|
#include <linux/suspend.h>
|
|
|
|
#include <linux/kbuild.h>
|
|
|
|
#include <asm/processor.h>
|
|
|
|
#include <asm/thread_info.h>
|
|
|
|
#include <asm/sigframe.h>
|
|
|
|
#include <asm/bootparam.h>
|
|
|
|
#include <asm/suspend.h>
|
|
|
|
|
|
|
|
#ifdef CONFIG_XEN
|
|
|
|
#include <xen/interface/xen.h>
|
|
|
|
#endif
|
|
|
|
|
2007-10-11 17:12:08 +08:00
|
|
|
#ifdef CONFIG_X86_32
|
|
|
|
# include "asm-offsets_32.c"
|
|
|
|
#else
|
|
|
|
# include "asm-offsets_64.c"
|
2007-07-19 16:49:26 +08:00
|
|
|
#endif
|
2011-02-09 16:24:34 +08:00
|
|
|
|
|
|
|
void common(void) {
|
2016-08-14 00:38:19 +08:00
|
|
|
BLANK();
|
|
|
|
OFFSET(TASK_threadsp, task_struct, thread.sp);
|
|
|
|
#ifdef CONFIG_CC_STACKPROTECTOR
|
|
|
|
OFFSET(TASK_stack_canary, task_struct, stack_canary);
|
|
|
|
#endif
|
|
|
|
|
2011-02-09 16:24:34 +08:00
|
|
|
BLANK();
|
2016-09-14 05:29:25 +08:00
|
|
|
OFFSET(TASK_TI_flags, task_struct, thread_info.flags);
|
2016-07-15 04:22:57 +08:00
|
|
|
OFFSET(TASK_addr_limit, task_struct, thread.addr_limit);
|
2011-02-09 16:24:34 +08:00
|
|
|
|
|
|
|
BLANK();
|
|
|
|
OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
|
|
|
|
|
|
|
|
BLANK();
|
|
|
|
OFFSET(pbe_address, pbe, address);
|
|
|
|
OFFSET(pbe_orig_address, pbe, orig_address);
|
|
|
|
OFFSET(pbe_next, pbe, next);
|
|
|
|
|
2015-04-12 21:14:45 +08:00
|
|
|
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
|
|
|
|
BLANK();
|
2015-09-05 15:32:41 +08:00
|
|
|
OFFSET(IA32_SIGCONTEXT_ax, sigcontext_32, ax);
|
|
|
|
OFFSET(IA32_SIGCONTEXT_bx, sigcontext_32, bx);
|
|
|
|
OFFSET(IA32_SIGCONTEXT_cx, sigcontext_32, cx);
|
|
|
|
OFFSET(IA32_SIGCONTEXT_dx, sigcontext_32, dx);
|
|
|
|
OFFSET(IA32_SIGCONTEXT_si, sigcontext_32, si);
|
|
|
|
OFFSET(IA32_SIGCONTEXT_di, sigcontext_32, di);
|
|
|
|
OFFSET(IA32_SIGCONTEXT_bp, sigcontext_32, bp);
|
|
|
|
OFFSET(IA32_SIGCONTEXT_sp, sigcontext_32, sp);
|
|
|
|
OFFSET(IA32_SIGCONTEXT_ip, sigcontext_32, ip);
|
2015-04-12 21:14:45 +08:00
|
|
|
|
|
|
|
BLANK();
|
|
|
|
OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext);
|
|
|
|
#endif
|
|
|
|
|
2011-02-09 16:24:34 +08:00
|
|
|
#ifdef CONFIG_PARAVIRT
|
|
|
|
BLANK();
|
|
|
|
OFFSET(PARAVIRT_PATCH_pv_cpu_ops, paravirt_patch_template, pv_cpu_ops);
|
|
|
|
OFFSET(PARAVIRT_PATCH_pv_irq_ops, paravirt_patch_template, pv_irq_ops);
|
|
|
|
OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
|
|
|
|
OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
|
|
|
|
OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
|
|
|
|
OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
|
|
|
|
OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_XEN
|
|
|
|
BLANK();
|
|
|
|
OFFSET(XEN_vcpu_info_mask, vcpu_info, evtchn_upcall_mask);
|
|
|
|
OFFSET(XEN_vcpu_info_pending, vcpu_info, evtchn_upcall_pending);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
BLANK();
|
|
|
|
OFFSET(BP_scratch, boot_params, scratch);
|
2017-02-06 19:22:43 +08:00
|
|
|
OFFSET(BP_secure_boot, boot_params, secure_boot);
|
2011-02-09 16:24:34 +08:00
|
|
|
OFFSET(BP_loadflags, boot_params, hdr.loadflags);
|
|
|
|
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);
|
x86/boot: Move compressed kernel to the end of the decompression buffer
This change makes later calculations about where the kernel is located
easier to reason about. To better understand this change, we must first
clarify what 'VO' and 'ZO' are. These values were introduced in commits
by hpa:
77d1a4999502 ("x86, boot: make symbols from the main vmlinux available")
37ba7ab5e33c ("x86, boot: make kernel_alignment adjustable; new bzImage fields")
Specifically:
All names prefixed with 'VO_':
- relate to the uncompressed kernel image
- the size of the VO image is: VO__end-VO__text ("VO_INIT_SIZE" define)
All names prefixed with 'ZO_':
- relate to the bootable compressed kernel image (boot/compressed/vmlinux),
which is composed of the following memory areas:
- head text
- compressed kernel (VO image and relocs table)
- decompressor code
- the size of the ZO image is: ZO__end - ZO_startup_32 ("ZO_INIT_SIZE" define, though see below)
The 'INIT_SIZE' value is used to find the larger of the two image sizes:
#define ZO_INIT_SIZE (ZO__end - ZO_startup_32 + ZO_z_extract_offset)
#define VO_INIT_SIZE (VO__end - VO__text)
#if ZO_INIT_SIZE > VO_INIT_SIZE
# define INIT_SIZE ZO_INIT_SIZE
#else
# define INIT_SIZE VO_INIT_SIZE
#endif
The current code uses extract_offset to decide where to position the
copied ZO (i.e. ZO starts at extract_offset). (This is why ZO_INIT_SIZE
currently includes the extract_offset.)
Why does z_extract_offset exist? It's needed because we are trying to minimize
the amount of RAM used for the whole act of creating an uncompressed, executable,
properly relocation-linked kernel image in system memory. We do this so that
kernels can be booted on even very small systems.
To achieve the goal of minimal memory consumption we have implemented an in-place
decompression strategy: instead of cleanly separating the VO and ZO images and
also allocating some memory for the decompression code's runtime needs, we instead
create this elaborate layout of memory buffers where the output (decompressed)
stream, as it progresses, overlaps with and destroys the input (compressed)
stream. This can only be done safely if the ZO image is placed to the end of the
VO range, plus a certain amount of safety distance to make sure that when the last
bytes of the VO range are decompressed, the compressed stream pointer is safely
beyond the end of the VO range.
z_extract_offset is calculated in arch/x86/boot/compressed/mkpiggy.c during
the build process, at a point when we know the exact compressed and
uncompressed size of the kernel images and can calculate this safe minimum
offset value. (Note that the mkpiggy.c calculation is not perfect, because
we don't know the decompressor used at that stage, so the z_extract_offset
calculation is necessarily imprecise and is mostly based on gzip internals -
we'll improve that in the next patch.)
When INIT_SIZE is bigger than VO_INIT_SIZE (uncommon but possible),
the copied ZO occupies the memory from extract_offset to the end of
decompression buffer. It overlaps with the soon-to-be-uncompressed kernel
like this:
|-----compressed kernel image------|
V V
0 extract_offset +INIT_SIZE
|-----------|---------------|-------------------------|--------|
| | | |
VO__text startup_32 of ZO VO__end ZO__end
^ ^
|-------uncompressed kernel image---------|
When INIT_SIZE is equal to VO_INIT_SIZE (likely) there's still space
left from end of ZO to the end of decompressing buffer, like below.
|-compressed kernel image-|
V V
0 extract_offset +INIT_SIZE
|-----------|---------------|-------------------------|--------|
| | | |
VO__text startup_32 of ZO ZO__end VO__end
^ ^
|------------uncompressed kernel image-------------|
To simplify calculations and avoid special cases, it is cleaner to
always place the compressed kernel image in memory so that ZO__end
is at the end of the decompression buffer, instead of placing t at
the start of extract_offset as is currently done.
This patch adds BP_init_size (which is the INIT_SIZE as passed in from
the boot_params) into asm-offsets.c to make it visible to the assembly
code.
Then when moving the ZO, it calculates the starting position of
the copied ZO (via BP_init_size and the ZO run size) so that the VO__end
will be at the end of the decompression buffer. To make the position
calculation safe, the end of ZO is page aligned (and a comment is added
to the existing VO alignment for good measure).
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
[ Rewrote changelog and comments. ]
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: lasse.collin@tukaani.org
Link: http://lkml.kernel.org/r/1461888548-32439-3-git-send-email-keescook@chromium.org
[ Rewrote the changelog some more. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2016-04-29 08:09:04 +08:00
|
|
|
OFFSET(BP_init_size, boot_params, hdr.init_size);
|
x86, efi: EFI boot stub support
There is currently a large divide between kernel development and the
development of EFI boot loaders. The idea behind this patch is to give
the kernel developers full control over the EFI boot process. As
H. Peter Anvin put it,
"The 'kernel carries its own stub' approach been very successful in
dealing with BIOS, and would make a lot of sense to me for EFI as
well."
This patch introduces an EFI boot stub that allows an x86 bzImage to
be loaded and executed by EFI firmware. The bzImage appears to the
firmware as an EFI application. Luckily there are enough free bits
within the bzImage header so that it can masquerade as an EFI
application, thereby coercing the EFI firmware into loading it and
jumping to its entry point. The beauty of this masquerading approach
is that both BIOS and EFI boot loaders can still load and run the same
bzImage, thereby allowing a single kernel image to work in any boot
environment.
The EFI boot stub supports multiple initrds, but they must exist on
the same partition as the bzImage. Command-line arguments for the
kernel can be appended after the bzImage name when run from the EFI
shell, e.g.
Shell> bzImage console=ttyS0 root=/dev/sdb initrd=initrd.img
v7:
- Fix checkpatch warnings.
v6:
- Try to allocate initrd memory just below hdr->inird_addr_max.
v5:
- load_options_size is UTF-16, which needs dividing by 2 to convert
to the corresponding ASCII size.
v4:
- Don't read more than image->load_options_size
v3:
- Fix following warnings when compiling CONFIG_EFI_STUB=n
arch/x86/boot/tools/build.c: In function ‘main’:
arch/x86/boot/tools/build.c:138:24: warning: unused variable ‘pe_header’
arch/x86/boot/tools/build.c:138:15: warning: unused variable ‘file_sz’
- As reported by Matthew Garrett, some Apple machines have GOPs that
don't have hardware attached. We need to weed these out by
searching for ones that handle the PCIIO protocol.
- Don't allocate memory if no initrds are on cmdline
- Don't trust image->load_options_size
Maarten Lankhorst noted:
- Don't strip first argument when booted from efibootmgr
- Don't allocate too much memory for cmdline
- Don't update cmdline_size, the kernel considers it read-only
- Don't accept '\n' for initrd names
v2:
- File alignment was too large, was 8192 should be 512. Reported by
Maarten Lankhorst on LKML.
- Added UGA support for graphics
- Use VIDEO_TYPE_EFI instead of hard-coded number.
- Move linelength assignment until after we've assigned depth
- Dynamically fill out AddressOfEntryPoint in tools/build.c
- Don't use magic number for GDT/TSS stuff. Requested by Andi Kleen
- The bzImage may need to be relocated as it may have been loaded at
a high address address by the firmware. This was required to get my
macbook booting because the firmware loaded it at 0x7cxxxxxx, which
triggers this error in decompress_kernel(),
if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
error("Destination address too large");
Cc: Mike Waychison <mikew@google.com>
Cc: Matthew Garrett <mjg@redhat.com>
Tested-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Link: http://lkml.kernel.org/r/1321383097.2657.9.camel@mfleming-mobl1.ger.corp.intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
2011-12-13 05:27:52 +08:00
|
|
|
OFFSET(BP_pref_address, boot_params, hdr.pref_address);
|
|
|
|
OFFSET(BP_code32_start, boot_params, hdr.code32_start);
|
2012-08-03 03:05:11 +08:00
|
|
|
|
|
|
|
BLANK();
|
|
|
|
DEFINE(PTREGS_SIZE, sizeof(struct pt_regs));
|
2011-02-09 16:24:34 +08:00
|
|
|
}
|