Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fbe4c22 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull misc x86 fixes from Ingo Molnar:
 "This contains:

   - EFI fixes
   - a boot printout fix
   - ASLR/kASLR fixes
   - intel microcode driver fixes
   - other misc fixes

  Most of the linecount comes from an EFI revert"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm/ASLR: Avoid PAGE_SIZE redefinition for UML subarch
  x86/microcode/intel: Handle truncated microcode images more robustly
  x86/microcode/intel: Guard against stack overflow in the loader
  x86, mm/ASLR: Fix stack randomization on 64-bit systems
  x86/mm/init: Fix incorrect page size in init_memory_mapping() printks
  x86/mm/ASLR: Propagate base load address calculation
  Documentation/x86: Fix path in zero-page.txt
  x86/apic: Fix the devicetree build in certain configs
  Revert "efi/libstub: Call get_memory_map() to obtain map and desc sizes"
  x86/efi: Avoid triple faults during EFI mixed mode calls
parents e2defd02 570e1aa8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ protocol of kernel. These should be filled by bootloader or 16-bit
real-mode setup code of the kernel. References/settings to it mainly
are in:

  arch/x86/include/asm/bootparam.h
  arch/x86/include/uapi/asm/bootparam.h


Offset	Proto	Name		Meaning
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone

vmlinux-objs-$(CONFIG_EFI_STUB) += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \
	$(objtree)/drivers/firmware/efi/libstub/lib.a
vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o

$(obj)/vmlinux: $(vmlinux-objs-y) FORCE
	$(call if_changed,ld)
+33 −1
Original line number Diff line number Diff line
@@ -14,6 +14,13 @@
static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@"
		LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION;

struct kaslr_setup_data {
	__u64 next;
	__u32 type;
	__u32 len;
	__u8 data[1];
} kaslr_setup_data;

#define I8254_PORT_CONTROL	0x43
#define I8254_PORT_COUNTER0	0x40
#define I8254_CMD_READBACK	0xC0
@@ -295,7 +302,29 @@ static unsigned long find_random_addr(unsigned long minimum,
	return slots_fetch_random();
}

unsigned char *choose_kernel_location(unsigned char *input,
static void add_kaslr_setup_data(struct boot_params *params, __u8 enabled)
{
	struct setup_data *data;

	kaslr_setup_data.type = SETUP_KASLR;
	kaslr_setup_data.len = 1;
	kaslr_setup_data.next = 0;
	kaslr_setup_data.data[0] = enabled;

	data = (struct setup_data *)(unsigned long)params->hdr.setup_data;

	while (data && data->next)
		data = (struct setup_data *)(unsigned long)data->next;

	if (data)
		data->next = (unsigned long)&kaslr_setup_data;
	else
		params->hdr.setup_data = (unsigned long)&kaslr_setup_data;

}

unsigned char *choose_kernel_location(struct boot_params *params,
				      unsigned char *input,
				      unsigned long input_size,
				      unsigned char *output,
				      unsigned long output_size)
@@ -306,14 +335,17 @@ unsigned char *choose_kernel_location(unsigned char *input,
#ifdef CONFIG_HIBERNATION
	if (!cmdline_find_option_bool("kaslr")) {
		debug_putstr("KASLR disabled by default...\n");
		add_kaslr_setup_data(params, 0);
		goto out;
	}
#else
	if (cmdline_find_option_bool("nokaslr")) {
		debug_putstr("KASLR disabled by cmdline...\n");
		add_kaslr_setup_data(params, 0);
		goto out;
	}
#endif
	add_kaslr_setup_data(params, 1);

	/* Record the various known unsafe memory ranges. */
	mem_avoid_init((unsigned long)input, input_size,
+0 −25
Original line number Diff line number Diff line
@@ -3,28 +3,3 @@
#include <asm/processor-flags.h>

#include "../../platform/efi/efi_stub_64.S"

#ifdef CONFIG_EFI_MIXED
	.code64
	.text
ENTRY(efi64_thunk)
	push	%rbp
	push	%rbx

	subq	$16, %rsp
	leaq	efi_exit32(%rip), %rax
	movl	%eax, 8(%rsp)
	leaq	efi_gdt64(%rip), %rax
	movl	%eax, 4(%rsp)
	movl	%eax, 2(%rax)		/* Fixup the gdt base address */
	leaq	efi32_boot_gdt(%rip), %rax
	movl	%eax, (%rsp)

	call	__efi64_thunk

	addq	$16, %rsp
	pop	%rbx
	pop	%rbp
	ret
ENDPROC(efi64_thunk)
#endif /* CONFIG_EFI_MIXED */
+196 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014, 2015 Intel Corporation; author Matt Fleming
 *
 * Early support for invoking 32-bit EFI services from a 64-bit kernel.
 *
 * Because this thunking occurs before ExitBootServices() we have to
 * restore the firmware's 32-bit GDT before we make EFI serivce calls,
 * since the firmware's 32-bit IDT is still currently installed and it
 * needs to be able to service interrupts.
 *
 * On the plus side, we don't have to worry about mangling 64-bit
 * addresses into 32-bits because we're executing with an identify
 * mapped pagetable and haven't transitioned to 64-bit virtual addresses
 * yet.
 */

#include <linux/linkage.h>
#include <asm/msr.h>
#include <asm/page_types.h>
#include <asm/processor-flags.h>
#include <asm/segment.h>

	.code64
	.text
ENTRY(efi64_thunk)
	push	%rbp
	push	%rbx

	subq	$8, %rsp
	leaq	efi_exit32(%rip), %rax
	movl	%eax, 4(%rsp)
	leaq	efi_gdt64(%rip), %rax
	movl	%eax, (%rsp)
	movl	%eax, 2(%rax)		/* Fixup the gdt base address */

	movl	%ds, %eax
	push	%rax
	movl	%es, %eax
	push	%rax
	movl	%ss, %eax
	push	%rax

	/*
	 * Convert x86-64 ABI params to i386 ABI
	 */
	subq	$32, %rsp
	movl	%esi, 0x0(%rsp)
	movl	%edx, 0x4(%rsp)
	movl	%ecx, 0x8(%rsp)
	movq	%r8, %rsi
	movl	%esi, 0xc(%rsp)
	movq	%r9, %rsi
	movl	%esi,  0x10(%rsp)

	sgdt	save_gdt(%rip)

	leaq	1f(%rip), %rbx
	movq	%rbx, func_rt_ptr(%rip)

	/*
	 * Switch to gdt with 32-bit segments. This is the firmware GDT
	 * that was installed when the kernel started executing. This
	 * pointer was saved at the EFI stub entry point in head_64.S.
	 */
	leaq	efi32_boot_gdt(%rip), %rax
	lgdt	(%rax)

	pushq	$__KERNEL_CS
	leaq	efi_enter32(%rip), %rax
	pushq	%rax
	lretq

1:	addq	$32, %rsp

	lgdt	save_gdt(%rip)

	pop	%rbx
	movl	%ebx, %ss
	pop	%rbx
	movl	%ebx, %es
	pop	%rbx
	movl	%ebx, %ds

	/*
	 * Convert 32-bit status code into 64-bit.
	 */
	test	%rax, %rax
	jz	1f
	movl	%eax, %ecx
	andl	$0x0fffffff, %ecx
	andl	$0xf0000000, %eax
	shl	$32, %rax
	or	%rcx, %rax
1:
	addq	$8, %rsp
	pop	%rbx
	pop	%rbp
	ret
ENDPROC(efi64_thunk)

ENTRY(efi_exit32)
	movq	func_rt_ptr(%rip), %rax
	push	%rax
	mov	%rdi, %rax
	ret
ENDPROC(efi_exit32)

	.code32
/*
 * EFI service pointer must be in %edi.
 *
 * The stack should represent the 32-bit calling convention.
 */
ENTRY(efi_enter32)
	movl	$__KERNEL_DS, %eax
	movl	%eax, %ds
	movl	%eax, %es
	movl	%eax, %ss

	/* Reload pgtables */
	movl	%cr3, %eax
	movl	%eax, %cr3

	/* Disable paging */
	movl	%cr0, %eax
	btrl	$X86_CR0_PG_BIT, %eax
	movl	%eax, %cr0

	/* Disable long mode via EFER */
	movl	$MSR_EFER, %ecx
	rdmsr
	btrl	$_EFER_LME, %eax
	wrmsr

	call	*%edi

	/* We must preserve return value */
	movl	%eax, %edi

	/*
	 * Some firmware will return with interrupts enabled. Be sure to
	 * disable them before we switch GDTs.
	 */
	cli

	movl	56(%esp), %eax
	movl	%eax, 2(%eax)
	lgdtl	(%eax)

	movl	%cr4, %eax
	btsl	$(X86_CR4_PAE_BIT), %eax
	movl	%eax, %cr4

	movl	%cr3, %eax
	movl	%eax, %cr3

	movl	$MSR_EFER, %ecx
	rdmsr
	btsl	$_EFER_LME, %eax
	wrmsr

	xorl	%eax, %eax
	lldt	%ax

	movl	60(%esp), %eax
	pushl	$__KERNEL_CS
	pushl	%eax

	/* Enable paging */
	movl	%cr0, %eax
	btsl	$X86_CR0_PG_BIT, %eax
	movl	%eax, %cr0
	lret
ENDPROC(efi_enter32)

	.data
	.balign	8
	.global	efi32_boot_gdt
efi32_boot_gdt:	.word	0
		.quad	0

save_gdt:	.word	0
		.quad	0
func_rt_ptr:	.quad	0

	.global efi_gdt64
efi_gdt64:
	.word	efi_gdt64_end - efi_gdt64
	.long	0			/* Filled out by user */
	.word	0
	.quad	0x0000000000000000	/* NULL descriptor */
	.quad	0x00af9a000000ffff	/* __KERNEL_CS */
	.quad	0x00cf92000000ffff	/* __KERNEL_DS */
	.quad	0x0080890000000000	/* TS descriptor */
	.quad   0x0000000000000000	/* TS continued */
efi_gdt64_end:
Loading