Skip to content

Commit

Permalink
Merge branch 'x86-trampoline-for-linus' of git://git.kernel.org/pub/s…
Browse files Browse the repository at this point in the history
…cm/linux/kernel/git/tip/tip

Pull x86 trampoline rework from H. Peter Anvin:
 "This code reworks all the "trampoline"/"realmode" code (various bits
  that need to live in the first megabyte of memory, most but not all of
  which runs in real mode at some point) in the kernel into a single
  object.  The main reason for doing this is that it eliminates the last
  place in the kernel where we needed pages to be mapped RWX.  This code
  separates all that code into proper R/RW/RX pages."

Fix up conflicts in arch/x86/kernel/Makefile (mca removed next to reboot
code), and arch/x86/kernel/reboot.c (reboot code moved around in one
branch, modified in this one), and arch/x86/tools/relocs.c (mostly same
code came in earlier due to working around the ld bugs just before the
3.4 release).

Also remove stale x86-relocs entry from scripts/.gitignore as per Peter
Anvin.

* commit '61f5446169046c217a5479517edac3a890c3bee7': (36 commits)
  x86, realmode: Move end signature into header.S
  x86, relocs: When printing an error, say relative or absolute
  x86, relocs: More relocations which may end up as absolute
  x86, relocs: Workaround for binutils 2.22.52.0.1 section bug
  xen-acpi-processor: Add missing #include <xen/xen.h>
  acpi, bgrd: Add missing <linux/io.h> to drivers/acpi/bgrt.c
  x86, realmode: Change EFER to a single u64 field
  x86, realmode: Move kernel/realmode.c to realmode/init.c
  x86, realmode: Move not-common bits out of trampoline_common.S
  x86, realmode: Mask out EFER.LMA when saving trampoline EFER
  x86, realmode: Fix no cache bits test in reboot_32.S
  x86, realmode: Make sure all generated files are listed in targets
  x86, realmode: build fix: remove duplicate build
  x86, realmode: read cr4 and EFER from kernel for 64-bit trampoline
  x86, realmode: fixes compilation issue in tboot.c
  x86, realmode: move relocs from scripts/ to arch/x86/tools
  x86, realmode: header for trampoline code
  x86, realmode: flattened rm hierachy
  x86, realmode: don't copy real_mode_header
  x86, realmode: fix 64-bit wakeup sequence
  ...
  • Loading branch information
Linus Torvalds committed May 30, 2012
2 parents 87a5af2 + 61f5446 commit 731a737
Show file tree
Hide file tree
Showing 59 changed files with 774 additions and 613 deletions.
2 changes: 1 addition & 1 deletion arch/x86/Kbuild
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

obj-$(CONFIG_KVM) += kvm/

# Xen paravirtualization support
Expand All @@ -7,6 +6,7 @@ obj-$(CONFIG_XEN) += xen/
# lguest paravirtualization support
obj-$(CONFIG_LGUEST_GUEST) += lguest/

obj-y += realmode/
obj-y += kernel/
obj-y += mm/

Expand Down
2 changes: 0 additions & 2 deletions arch/x86/include/asm/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include <asm/processor.h>
#include <asm/mmu.h>
#include <asm/mpspec.h>
#include <asm/trampoline.h>

#define COMPILER_DEPENDENT_INT64 long long
#define COMPILER_DEPENDENT_UINT64 unsigned long long
Expand Down Expand Up @@ -118,7 +117,6 @@ static inline void acpi_disable_pci(void)
extern int acpi_suspend_lowlevel(void);

extern const unsigned char acpi_wakeup_code[];
#define acpi_wakeup_address (__pa(TRAMPOLINE_SYM(acpi_wakeup_code)))

/* early initialization routine */
extern void acpi_reserve_wakeup_memory(void);
Expand Down
7 changes: 6 additions & 1 deletion arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,13 +544,16 @@ static inline void load_sp0(struct tss_struct *tss,
* enable), so that any CPU's that boot up
* after us can get the correct flags.
*/
extern unsigned long mmu_cr4_features;
extern unsigned long mmu_cr4_features;
extern u32 *trampoline_cr4_features;

static inline void set_in_cr4(unsigned long mask)
{
unsigned long cr4;

mmu_cr4_features |= mask;
if (trampoline_cr4_features)
*trampoline_cr4_features = mmu_cr4_features;
cr4 = read_cr4();
cr4 |= mask;
write_cr4(cr4);
Expand All @@ -561,6 +564,8 @@ static inline void clear_in_cr4(unsigned long mask)
unsigned long cr4;

mmu_cr4_features &= ~mask;
if (trampoline_cr4_features)
*trampoline_cr4_features = mmu_cr4_features;
cr4 = read_cr4();
cr4 &= ~mask;
write_cr4(cr4);
Expand Down
62 changes: 62 additions & 0 deletions arch/x86/include/asm/realmode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef _ARCH_X86_REALMODE_H
#define _ARCH_X86_REALMODE_H

#include <linux/types.h>
#include <asm/io.h>

/* This must match data at realmode.S */
struct real_mode_header {
u32 text_start;
u32 ro_end;
/* SMP trampoline */
u32 trampoline_start;
u32 trampoline_status;
u32 trampoline_header;
#ifdef CONFIG_X86_64
u32 trampoline_pgd;
#endif
/* ACPI S3 wakeup */
#ifdef CONFIG_ACPI_SLEEP
u32 wakeup_start;
u32 wakeup_header;
#endif
/* APM/BIOS reboot */
#ifdef CONFIG_X86_32
u32 machine_real_restart_asm;
#endif
};

/* This must match data at trampoline_32/64.S */
struct trampoline_header {
#ifdef CONFIG_X86_32
u32 start;
u16 gdt_pad;
u16 gdt_limit;
u32 gdt_base;
#else
u64 start;
u64 efer;
u32 cr4;
#endif
};

extern struct real_mode_header *real_mode_header;
extern unsigned char real_mode_blob_end[];

extern unsigned long init_rsp;
extern unsigned long initial_code;
extern unsigned long initial_gs;

extern unsigned char real_mode_blob[];
extern unsigned char real_mode_relocs[];

#ifdef CONFIG_X86_32
extern unsigned char startup_32_smp[];
extern unsigned char boot_gdt[];
#else
extern unsigned char secondary_startup_64[];
#endif

extern void __init setup_real_mode(void);

#endif /* _ARCH_X86_REALMODE_H */
39 changes: 0 additions & 39 deletions arch/x86/include/asm/trampoline.h

This file was deleted.

2 changes: 0 additions & 2 deletions arch/x86/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ obj-y += tsc.o io_delay.o rtc.o
obj-y += pci-iommu_table.o
obj-y += resource.o

obj-y += trampoline.o trampoline_$(BITS).o
obj-y += process.o
obj-y += i387.o xsave.o
obj-y += ptrace.o
Expand All @@ -48,7 +47,6 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += cpu/
obj-y += acpi/
obj-y += reboot.o
obj-$(CONFIG_X86_32) += reboot_32.o
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_PCI) += early-quirks.o
Expand Down
9 changes: 1 addition & 8 deletions arch/x86/kernel/acpi/Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
subdir- := realmode

obj-$(CONFIG_ACPI) += boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_rm.o wakeup_$(BITS).o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o

ifneq ($(CONFIG_ACPI_PROCESSOR),)
obj-y += cstate.o
endif

$(obj)/wakeup_rm.o: $(obj)/realmode/wakeup.bin

$(obj)/realmode/wakeup.bin: FORCE
$(Q)$(MAKE) $(build)=$(obj)/realmode

3 changes: 0 additions & 3 deletions arch/x86/kernel/acpi/realmode/.gitignore

This file was deleted.

59 changes: 0 additions & 59 deletions arch/x86/kernel/acpi/realmode/Makefile

This file was deleted.

1 change: 0 additions & 1 deletion arch/x86/kernel/acpi/realmode/bioscall.S

This file was deleted.

1 change: 0 additions & 1 deletion arch/x86/kernel/acpi/realmode/copy.S

This file was deleted.

1 change: 0 additions & 1 deletion arch/x86/kernel/acpi/realmode/regs.c

This file was deleted.

1 change: 0 additions & 1 deletion arch/x86/kernel/acpi/realmode/video-bios.c

This file was deleted.

1 change: 0 additions & 1 deletion arch/x86/kernel/acpi/realmode/video-mode.c

This file was deleted.

1 change: 0 additions & 1 deletion arch/x86/kernel/acpi/realmode/video-vesa.c

This file was deleted.

1 change: 0 additions & 1 deletion arch/x86/kernel/acpi/realmode/video-vga.c

This file was deleted.

62 changes: 0 additions & 62 deletions arch/x86/kernel/acpi/realmode/wakeup.lds.S

This file was deleted.

33 changes: 4 additions & 29 deletions arch/x86/kernel/acpi/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
#include <asm/desc.h>
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/realmode.h>

#include "realmode/wakeup.h"
#include "../../realmode/rm/wakeup.h"
#include "sleep.h"

unsigned long acpi_realmode_flags;
Expand All @@ -36,41 +37,16 @@ asmlinkage void acpi_enter_s3(void)
*/
int acpi_suspend_lowlevel(void)
{
struct wakeup_header *header;
/* address in low memory of the wakeup routine. */
char *acpi_realmode;
struct wakeup_header *header =
(struct wakeup_header *) __va(real_mode_header->wakeup_header);

acpi_realmode = TRAMPOLINE_SYM(acpi_wakeup_code);

header = (struct wakeup_header *)(acpi_realmode + WAKEUP_HEADER_OFFSET);
if (header->signature != WAKEUP_HEADER_SIGNATURE) {
printk(KERN_ERR "wakeup header does not match\n");
return -EINVAL;
}

header->video_mode = saved_video_mode;

header->wakeup_jmp_seg = acpi_wakeup_address >> 4;

/*
* Set up the wakeup GDT. We set these up as Big Real Mode,
* that is, with limits set to 4 GB. At least the Lenovo
* Thinkpad X61 is known to need this for the video BIOS
* initialization quirk to work; this is likely to also
* be the case for other laptops or integrated video devices.
*/

/* GDT[0]: GDT self-pointer */
header->wakeup_gdt[0] =
(u64)(sizeof(header->wakeup_gdt) - 1) +
((u64)__pa(&header->wakeup_gdt) << 16);
/* GDT[1]: big real mode-like code segment */
header->wakeup_gdt[1] =
GDT_ENTRY(0x809b, acpi_wakeup_address, 0xfffff);
/* GDT[2]: big real mode-like data segment */
header->wakeup_gdt[2] =
GDT_ENTRY(0x8093, acpi_wakeup_address, 0xfffff);

#ifndef CONFIG_64BIT
store_gdt((struct desc_ptr *)&header->pmode_gdt);

Expand All @@ -95,7 +71,6 @@ int acpi_suspend_lowlevel(void)
header->pmode_cr3 = (u32)__pa(&initial_page_table);
saved_magic = 0x12345678;
#else /* CONFIG_64BIT */
header->trampoline_segment = trampoline_address() >> 4;
#ifdef CONFIG_SMP
stack_start = (unsigned long)temp_stack + sizeof(temp_stack);
early_gdt_descr.address =
Expand Down
Loading

0 comments on commit 731a737

Please sign in to comment.