All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Slaby <jslaby@suse.cz>
To: stable@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
	"H. Peter Anvin" <hpa@linux.intel.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Borislav Petkov <bp@alien8.de>,
	Andrew Lutomriski <amluto@gmail.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Dirk Hohndel <dirk@hohndel.org>,
	Arjan van de Ven <arjan.van.de.ven@intel.com>,
	comex <comexk@gmail.com>,
	Alexander van Heukelum <heukelum@fastmail.fm>,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Jiri Slaby <jslaby@suse.cz>
Subject: [PATCH 3.12 020/104] x86-64, espfix: Don't leak bits 31:16 of %esp returning to 16-bit stack
Date: Wed, 20 Aug 2014 13:42:43 +0200	[thread overview]
Message-ID: <7e329475de1f97df56e1cfa412e5b3479994c202.1408535000.git.jslaby@suse.cz> (raw)
In-Reply-To: <cbcbb4c4826ff594b091e143b0f049f13ab7a64e.1408535000.git.jslaby@suse.cz>
In-Reply-To: <cover.1408535000.git.jslaby@suse.cz>

From: "H. Peter Anvin" <hpa@linux.intel.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 3891a04aafd668686239349ea58f3314ea2af86b upstream.

The IRET instruction, when returning to a 16-bit segment, only
restores the bottom 16 bits of the user space stack pointer.  This
causes some 16-bit software to break, but it also leaks kernel state
to user space.  We have a software workaround for that ("espfix") for
the 32-bit kernel, but it relies on a nonzero stack segment base which
is not available in 64-bit mode.

In checkin:

    b3b42ac2cbae x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels

we "solved" this by forbidding 16-bit segments on 64-bit kernels, with
the logic that 16-bit support is crippled on 64-bit kernels anyway (no
V86 support), but it turns out that people are doing stuff like
running old Win16 binaries under Wine and expect it to work.

This works around this by creating percpu "ministacks", each of which
is mapped 2^16 times 64K apart.  When we detect that the return SS is
on the LDT, we copy the IRET frame to the ministack and use the
relevant alias to return to userspace.  The ministacks are mapped
readonly, so if IRET faults we promote #GP to #DF which is an IST
vector and thus has its own stack; we then do the fixup in the #DF
handler.

(Making #GP an IST exception would make the msr_safe functions unsafe
in NMI/MC context, and quite possibly have other effects.)

Special thanks to:

- Andy Lutomirski, for the suggestion of using very small stack slots
  and copy (as opposed to map) the IRET frame there, and for the
  suggestion to mark them readonly and let the fault promote to #DF.
- Konrad Wilk for paravirt fixup and testing.
- Borislav Petkov for testing help and useful comments.

Reported-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/1398816946-3351-1-git-send-email-hpa@linux.intel.com
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andrew Lutomriski <amluto@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Dirk Hohndel <dirk@hohndel.org>
Cc: Arjan van de Ven <arjan.van.de.ven@intel.com>
Cc: comex <comexk@gmail.com>
Cc: Alexander van Heukelum <heukelum@fastmail.fm>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: <stable@vger.kernel.org> # consider after upstream merge
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 Documentation/x86/x86_64/mm.txt         |   2 +
 arch/x86/include/asm/pgtable_64_types.h |   2 +
 arch/x86/include/asm/setup.h            |   3 +
 arch/x86/kernel/Makefile                |   1 +
 arch/x86/kernel/entry_64.S              |  73 ++++++++++-
 arch/x86/kernel/espfix_64.c             | 208 ++++++++++++++++++++++++++++++++
 arch/x86/kernel/ldt.c                   |  11 --
 arch/x86/kernel/smpboot.c               |   7 ++
 arch/x86/mm/dump_pagetables.c           |  31 +++--
 init/main.c                             |   4 +
 10 files changed, 316 insertions(+), 26 deletions(-)
 create mode 100644 arch/x86/kernel/espfix_64.c

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 881582f75c9c..bd4370487b07 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -12,6 +12,8 @@ ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
 ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
 ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
 ... unused hole ...
+ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
+... unused hole ...
 ffffffff80000000 - ffffffffa0000000 (=512 MB)  kernel text mapping, from phys 0
 ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 2d883440cb9a..b1609f2c524c 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -61,6 +61,8 @@ typedef struct { pteval_t pte; } pte_t;
 #define MODULES_VADDR    _AC(0xffffffffa0000000, UL)
 #define MODULES_END      _AC(0xffffffffff000000, UL)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
+#define ESPFIX_PGD_ENTRY _AC(-2, UL)
+#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
 
 #define EARLY_DYNAMIC_PAGE_TABLES	64
 
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 347555492dad..82bb2c8f13f1 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -62,6 +62,9 @@ extern void x86_ce4100_early_setup(void);
 static inline void x86_ce4100_early_setup(void) { }
 #endif
 
+extern void init_espfix_bsp(void);
+extern void init_espfix_ap(void);
+
 #ifndef _SETUP
 
 /*
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index a5408b965c9d..d5c94c90716b 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
 obj-y			+= syscall_$(BITS).o
 obj-$(CONFIG_X86_64)	+= vsyscall_64.o
 obj-$(CONFIG_X86_64)	+= vsyscall_emu_64.o
+obj-$(CONFIG_X86_64)	+= espfix_64.o
 obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 9ce256739175..383503cc9231 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -58,6 +58,7 @@
 #include <asm/asm.h>
 #include <asm/context_tracking.h>
 #include <asm/smap.h>
+#include <asm/pgtable_types.h>
 #include <linux/err.h>
 
 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
@@ -1040,8 +1041,16 @@ restore_args:
 	RESTORE_ARGS 1,8,1
 
 irq_return:
+	/*
+	 * Are we returning to a stack segment from the LDT?  Note: in
+	 * 64-bit mode SS:RSP on the exception stack is always valid.
+	 */
+	testb $4,(SS-RIP)(%rsp)
+	jnz irq_return_ldt
+
+irq_return_iret:
 	INTERRUPT_RETURN
-	_ASM_EXTABLE(irq_return, bad_iret)
+	_ASM_EXTABLE(irq_return_iret, bad_iret)
 
 #ifdef CONFIG_PARAVIRT
 ENTRY(native_iret)
@@ -1049,6 +1058,30 @@ ENTRY(native_iret)
 	_ASM_EXTABLE(native_iret, bad_iret)
 #endif
 
+irq_return_ldt:
+	pushq_cfi %rax
+	pushq_cfi %rdi
+	SWAPGS
+	movq PER_CPU_VAR(espfix_waddr),%rdi
+	movq %rax,(0*8)(%rdi)	/* RAX */
+	movq (2*8)(%rsp),%rax	/* RIP */
+	movq %rax,(1*8)(%rdi)
+	movq (3*8)(%rsp),%rax	/* CS */
+	movq %rax,(2*8)(%rdi)
+	movq (4*8)(%rsp),%rax	/* RFLAGS */
+	movq %rax,(3*8)(%rdi)
+	movq (6*8)(%rsp),%rax	/* SS */
+	movq %rax,(5*8)(%rdi)
+	movq (5*8)(%rsp),%rax	/* RSP */
+	movq %rax,(4*8)(%rdi)
+	andl $0xffff0000,%eax
+	popq_cfi %rdi
+	orq PER_CPU_VAR(espfix_stack),%rax
+	SWAPGS
+	movq %rax,%rsp
+	popq_cfi %rax
+	jmp irq_return_iret
+
 	.section .fixup,"ax"
 bad_iret:
 	/*
@@ -1112,9 +1145,41 @@ ENTRY(retint_kernel)
 	call preempt_schedule_irq
 	jmp exit_intr
 #endif
-
 	CFI_ENDPROC
 END(common_interrupt)
+
+	/*
+	 * If IRET takes a fault on the espfix stack, then we
+	 * end up promoting it to a doublefault.  In that case,
+	 * modify the stack to make it look like we just entered
+	 * the #GP handler from user space, similar to bad_iret.
+	 */
+	ALIGN
+__do_double_fault:
+	XCPT_FRAME 1 RDI+8
+	movq RSP(%rdi),%rax		/* Trap on the espfix stack? */
+	sarq $PGDIR_SHIFT,%rax
+	cmpl $ESPFIX_PGD_ENTRY,%eax
+	jne do_double_fault		/* No, just deliver the fault */
+	cmpl $__KERNEL_CS,CS(%rdi)
+	jne do_double_fault
+	movq RIP(%rdi),%rax
+	cmpq $irq_return_iret,%rax
+#ifdef CONFIG_PARAVIRT
+	je 1f
+	cmpq $native_iret,%rax
+#endif
+	jne do_double_fault		/* This shouldn't happen... */
+1:
+	movq PER_CPU_VAR(kernel_stack),%rax
+	subq $(6*8-KERNEL_STACK_OFFSET),%rax	/* Reset to original stack */
+	movq %rax,RSP(%rdi)
+	movq $0,(%rax)			/* Missing (lost) #GP error code */
+	movq $general_protection,RIP(%rdi)
+	retq
+	CFI_ENDPROC
+END(__do_double_fault)
+
 /*
  * End of kprobes section
  */
@@ -1305,7 +1370,7 @@ zeroentry overflow do_overflow
 zeroentry bounds do_bounds
 zeroentry invalid_op do_invalid_op
 zeroentry device_not_available do_device_not_available
-paranoiderrorentry double_fault do_double_fault
+paranoiderrorentry double_fault __do_double_fault
 zeroentry coprocessor_segment_overrun do_coprocessor_segment_overrun
 errorentry invalid_TSS do_invalid_TSS
 errorentry segment_not_present do_segment_not_present
@@ -1592,7 +1657,7 @@ error_sti:
  */
 error_kernelspace:
 	incl %ebx
-	leaq irq_return(%rip),%rcx
+	leaq irq_return_iret(%rip),%rcx
 	cmpq %rcx,RIP+8(%rsp)
 	je error_swapgs
 	movl %ecx,%eax	/* zero extend */
diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c
new file mode 100644
index 000000000000..8a64da36310f
--- /dev/null
+++ b/arch/x86/kernel/espfix_64.c
@@ -0,0 +1,208 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2014 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This program is free software; you can redistribute it and/or modify it
+ *   under the terms and conditions of the GNU General Public License,
+ *   version 2, as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope it will be useful, but WITHOUT
+ *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *   more details.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * The IRET instruction, when returning to a 16-bit segment, only
+ * restores the bottom 16 bits of the user space stack pointer.  This
+ * causes some 16-bit software to break, but it also leaks kernel state
+ * to user space.
+ *
+ * This works around this by creating percpu "ministacks", each of which
+ * is mapped 2^16 times 64K apart.  When we detect that the return SS is
+ * on the LDT, we copy the IRET frame to the ministack and use the
+ * relevant alias to return to userspace.  The ministacks are mapped
+ * readonly, so if the IRET fault we promote #GP to #DF which is an IST
+ * vector and thus has its own stack; we then do the fixup in the #DF
+ * handler.
+ *
+ * This file sets up the ministacks and the related page tables.  The
+ * actual ministack invocation is in entry_64.S.
+ */
+
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/kernel.h>
+#include <linux/percpu.h>
+#include <linux/gfp.h>
+#include <linux/random.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/setup.h>
+
+/*
+ * Note: we only need 6*8 = 48 bytes for the espfix stack, but round
+ * it up to a cache line to avoid unnecessary sharing.
+ */
+#define ESPFIX_STACK_SIZE	(8*8UL)
+#define ESPFIX_STACKS_PER_PAGE	(PAGE_SIZE/ESPFIX_STACK_SIZE)
+
+/* There is address space for how many espfix pages? */
+#define ESPFIX_PAGE_SPACE	(1UL << (PGDIR_SHIFT-PAGE_SHIFT-16))
+
+#define ESPFIX_MAX_CPUS		(ESPFIX_STACKS_PER_PAGE * ESPFIX_PAGE_SPACE)
+#if CONFIG_NR_CPUS > ESPFIX_MAX_CPUS
+# error "Need more than one PGD for the ESPFIX hack"
+#endif
+
+#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+
+/* This contains the *bottom* address of the espfix stack */
+DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack);
+DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr);
+
+/* Initialization mutex - should this be a spinlock? */
+static DEFINE_MUTEX(espfix_init_mutex);
+
+/* Page allocation bitmap - each page serves ESPFIX_STACKS_PER_PAGE CPUs */
+#define ESPFIX_MAX_PAGES  DIV_ROUND_UP(CONFIG_NR_CPUS, ESPFIX_STACKS_PER_PAGE)
+static void *espfix_pages[ESPFIX_MAX_PAGES];
+
+static __page_aligned_bss pud_t espfix_pud_page[PTRS_PER_PUD]
+	__aligned(PAGE_SIZE);
+
+static unsigned int page_random, slot_random;
+
+/*
+ * This returns the bottom address of the espfix stack for a specific CPU.
+ * The math allows for a non-power-of-two ESPFIX_STACK_SIZE, in which case
+ * we have to account for some amount of padding at the end of each page.
+ */
+static inline unsigned long espfix_base_addr(unsigned int cpu)
+{
+	unsigned long page, slot;
+	unsigned long addr;
+
+	page = (cpu / ESPFIX_STACKS_PER_PAGE) ^ page_random;
+	slot = (cpu + slot_random) % ESPFIX_STACKS_PER_PAGE;
+	addr = (page << PAGE_SHIFT) + (slot * ESPFIX_STACK_SIZE);
+	addr = (addr & 0xffffUL) | ((addr & ~0xffffUL) << 16);
+	addr += ESPFIX_BASE_ADDR;
+	return addr;
+}
+
+#define PTE_STRIDE        (65536/PAGE_SIZE)
+#define ESPFIX_PTE_CLONES (PTRS_PER_PTE/PTE_STRIDE)
+#define ESPFIX_PMD_CLONES PTRS_PER_PMD
+#define ESPFIX_PUD_CLONES (65536/(ESPFIX_PTE_CLONES*ESPFIX_PMD_CLONES))
+
+#define PGTABLE_PROT	  ((_KERNPG_TABLE & ~_PAGE_RW) | _PAGE_NX)
+
+static void init_espfix_random(void)
+{
+	unsigned long rand;
+
+	/*
+	 * This is run before the entropy pools are initialized,
+	 * but this is hopefully better than nothing.
+	 */
+	if (!arch_get_random_long(&rand)) {
+		/* The constant is an arbitrary large prime */
+		rdtscll(rand);
+		rand *= 0xc345c6b72fd16123UL;
+	}
+
+	slot_random = rand % ESPFIX_STACKS_PER_PAGE;
+	page_random = (rand / ESPFIX_STACKS_PER_PAGE)
+		& (ESPFIX_PAGE_SPACE - 1);
+}
+
+void __init init_espfix_bsp(void)
+{
+	pgd_t *pgd_p;
+	pteval_t ptemask;
+
+	ptemask = __supported_pte_mask;
+
+	/* Install the espfix pud into the kernel page directory */
+	pgd_p = &init_level4_pgt[pgd_index(ESPFIX_BASE_ADDR)];
+	pgd_populate(&init_mm, pgd_p, (pud_t *)espfix_pud_page);
+
+	/* Randomize the locations */
+	init_espfix_random();
+
+	/* The rest is the same as for any other processor */
+	init_espfix_ap();
+}
+
+void init_espfix_ap(void)
+{
+	unsigned int cpu, page;
+	unsigned long addr;
+	pud_t pud, *pud_p;
+	pmd_t pmd, *pmd_p;
+	pte_t pte, *pte_p;
+	int n;
+	void *stack_page;
+	pteval_t ptemask;
+
+	/* We only have to do this once... */
+	if (likely(this_cpu_read(espfix_stack)))
+		return;		/* Already initialized */
+
+	cpu = smp_processor_id();
+	addr = espfix_base_addr(cpu);
+	page = cpu/ESPFIX_STACKS_PER_PAGE;
+
+	/* Did another CPU already set this up? */
+	stack_page = ACCESS_ONCE(espfix_pages[page]);
+	if (likely(stack_page))
+		goto done;
+
+	mutex_lock(&espfix_init_mutex);
+
+	/* Did we race on the lock? */
+	stack_page = ACCESS_ONCE(espfix_pages[page]);
+	if (stack_page)
+		goto unlock_done;
+
+	ptemask = __supported_pte_mask;
+
+	pud_p = &espfix_pud_page[pud_index(addr)];
+	pud = *pud_p;
+	if (!pud_present(pud)) {
+		pmd_p = (pmd_t *)__get_free_page(PGALLOC_GFP);
+		pud = __pud(__pa(pmd_p) | (PGTABLE_PROT & ptemask));
+		paravirt_alloc_pud(&init_mm, __pa(pmd_p) >> PAGE_SHIFT);
+		for (n = 0; n < ESPFIX_PUD_CLONES; n++)
+			set_pud(&pud_p[n], pud);
+	}
+
+	pmd_p = pmd_offset(&pud, addr);
+	pmd = *pmd_p;
+	if (!pmd_present(pmd)) {
+		pte_p = (pte_t *)__get_free_page(PGALLOC_GFP);
+		pmd = __pmd(__pa(pte_p) | (PGTABLE_PROT & ptemask));
+		paravirt_alloc_pmd(&init_mm, __pa(pte_p) >> PAGE_SHIFT);
+		for (n = 0; n < ESPFIX_PMD_CLONES; n++)
+			set_pmd(&pmd_p[n], pmd);
+	}
+
+	pte_p = pte_offset_kernel(&pmd, addr);
+	stack_page = (void *)__get_free_page(GFP_KERNEL);
+	pte = __pte(__pa(stack_page) | (__PAGE_KERNEL_RO & ptemask));
+	paravirt_alloc_pte(&init_mm, __pa(stack_page) >> PAGE_SHIFT);
+	for (n = 0; n < ESPFIX_PTE_CLONES; n++)
+		set_pte(&pte_p[n*PTE_STRIDE], pte);
+
+	/* Job is done for this CPU and any CPU which shares this page */
+	ACCESS_ONCE(espfix_pages[page]) = stack_page;
+
+unlock_done:
+	mutex_unlock(&espfix_init_mutex);
+done:
+	this_cpu_write(espfix_stack, addr);
+	this_cpu_write(espfix_waddr, (unsigned long)stack_page
+		       + (addr & ~PAGE_MASK));
+}
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index af1d14a9ebda..ebc987398923 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -229,17 +229,6 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
 		}
 	}
 
-	/*
-	 * On x86-64 we do not support 16-bit segments due to
-	 * IRET leaking the high bits of the kernel stack address.
-	 */
-#ifdef CONFIG_X86_64
-	if (!ldt_info.seg_32bit) {
-		error = -EINVAL;
-		goto out_unlock;
-	}
-#endif
-
 	fill_ldt(&ldt, &ldt_info);
 	if (oldmode)
 		ldt.avl = 0;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 6cacab671f9b..a7340d7d6d06 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -265,6 +265,13 @@ static void notrace start_secondary(void *unused)
 	check_tsc_sync_target();
 
 	/*
+	 * Enable the espfix hack for this CPU
+	 */
+#ifdef CONFIG_X86_64
+	init_espfix_ap();
+#endif
+
+	/*
 	 * We need to hold vector_lock so there the set of online cpus
 	 * does not change while we are assigning vectors to cpus.  Holding
 	 * this lock ensures we don't half assign or remove an irq from a cpu.
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 0002a3a33081..3620928631ce 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -30,11 +30,13 @@ struct pg_state {
 	unsigned long start_address;
 	unsigned long current_address;
 	const struct addr_marker *marker;
+	unsigned long lines;
 };
 
 struct addr_marker {
 	unsigned long start_address;
 	const char *name;
+	unsigned long max_lines;
 };
 
 /* indices for address_markers; keep sync'd w/ address_markers below */
@@ -45,6 +47,7 @@ enum address_markers_idx {
 	LOW_KERNEL_NR,
 	VMALLOC_START_NR,
 	VMEMMAP_START_NR,
+	ESPFIX_START_NR,
 	HIGH_KERNEL_NR,
 	MODULES_VADDR_NR,
 	MODULES_END_NR,
@@ -67,6 +70,7 @@ static struct addr_marker address_markers[] = {
 	{ PAGE_OFFSET,		"Low Kernel Mapping" },
 	{ VMALLOC_START,        "vmalloc() Area" },
 	{ VMEMMAP_START,        "Vmemmap" },
+	{ ESPFIX_BASE_ADDR,	"ESPfix Area", 16 },
 	{ __START_KERNEL_map,   "High Kernel Mapping" },
 	{ MODULES_VADDR,        "Modules" },
 	{ MODULES_END,          "End Modules" },
@@ -163,7 +167,7 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 		      pgprot_t new_prot, int level)
 {
 	pgprotval_t prot, cur;
-	static const char units[] = "KMGTPE";
+	static const char units[] = "BKMGTPE";
 
 	/*
 	 * If we have a "break" in the series, we need to flush the state that
@@ -178,6 +182,7 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 		st->current_prot = new_prot;
 		st->level = level;
 		st->marker = address_markers;
+		st->lines = 0;
 		seq_printf(m, "---[ %s ]---\n", st->marker->name);
 	} else if (prot != cur || level != st->level ||
 		   st->current_address >= st->marker[1].start_address) {
@@ -188,17 +193,21 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 		/*
 		 * Now print the actual finished series
 		 */
-		seq_printf(m, "0x%0*lx-0x%0*lx   ",
-			   width, st->start_address,
-			   width, st->current_address);
-
-		delta = (st->current_address - st->start_address) >> 10;
-		while (!(delta & 1023) && unit[1]) {
-			delta >>= 10;
-			unit++;
+		if (!st->marker->max_lines ||
+		    st->lines < st->marker->max_lines) {
+			seq_printf(m, "0x%0*lx-0x%0*lx   ",
+				   width, st->start_address,
+				   width, st->current_address);
+
+			delta = (st->current_address - st->start_address) >> 10;
+			while (!(delta & 1023) && unit[1]) {
+				delta >>= 10;
+				unit++;
+			}
+			seq_printf(m, "%9lu%c ", delta, *unit);
+			printk_prot(m, st->current_prot, st->level);
 		}
-		seq_printf(m, "%9lu%c ", delta, *unit);
-		printk_prot(m, st->current_prot, st->level);
+		st->lines++;
 
 		/*
 		 * We print markers for special areas of address space,
diff --git a/init/main.c b/init/main.c
index 63d3e8f2970c..8e35b39b5a80 100644
--- a/init/main.c
+++ b/init/main.c
@@ -610,6 +610,10 @@ asmlinkage void __init start_kernel(void)
 	if (efi_enabled(EFI_RUNTIME_SERVICES))
 		efi_enter_virtual_mode();
 #endif
+#ifdef CONFIG_X86_64
+	/* Should be run before the first non-init thread is created */
+	init_espfix_bsp();
+#endif
 	thread_info_cache_init();
 	cred_init();
 	fork_init(totalram_pages);
-- 
2.0.4


  parent reply	other threads:[~2014-08-20 12:03 UTC|newest]

Thread overview: 119+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-20 11:43 [PATCH 3.12 000/104] 3.12.27-stable review Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 001/104] s390/ptrace: fix PSW mask check Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 002/104] crypto: af_alg - properly label AF_ALG socket Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 003/104] ARM: 8115/1: LPAE: reduce damage caused by idmap to virtual memory layout Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 004/104] ath9k: fix aggregation session lockup Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 005/104] cfg80211: fix mic_failure tracing Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 006/104] rapidio/tsi721_dma: fix failure to obtain transaction descriptor Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 007/104] scsi: handle flush errors properly Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 008/104] mm/page-writeback.c: fix divide by zero in bdi_dirty_limits() Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 009/104] mm, thp: do not allow thp faults to avoid cpuset restrictions Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 010/104] memcg: oom_notify use-after-free fix Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 011/104] staging: vt6655: Fix disassociated messages every 10 seconds Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 012/104] iio:bma180: Fix scale factors to report correct acceleration units Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 013/104] iio:bma180: Missing check for frequency fractional part Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 014/104] iio: buffer: Fix demux table creation Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 015/104] dm bufio: fully initialize shrinker Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 016/104] dm cache: fix race affecting dirty block count Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 017/104] printk: rename printk_sched to printk_deferred Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 018/104] timer: Fix lock inversion between hrtimer_bases.lock and scheduler locks Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 019/104] Revert "x86-64, modify_ldt: Make support for 16-bit segments a runtime option" Jiri Slaby
2014-08-20 11:42 ` Jiri Slaby [this message]
2014-08-20 11:42 ` [PATCH 3.12 021/104] x86, espfix: Move espfix definitions into a separate header file Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 022/104] x86, espfix: Fix broken header guard Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 023/104] x86, espfix: Make espfix64 a Kconfig option, fix UML Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 024/104] x86, espfix: Make it possible to disable 16-bit support Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 025/104] x86_64/entry/xen: Do not invoke espfix64 on Xen Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 026/104] staging: vt6655: Fix Warning on boot handle_irq_event_percpu Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 027/104] Revert "mac80211: move "bufferable MMPDU" check to fix AP mode scan" Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 028/104] xtensa: add fixup for double exception raised in window overflow Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 029/104] net/l2tp: don't fall back on UDP [get|set]sockopt Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 030/104] lib/btree.c: fix leak of whole btree nodes Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 031/104] x86/espfix/xen: Fix allocation of pages for paravirt page tables Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 032/104] bnx2x: fix crash during TSO tunneling Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 033/104] inetpeer: get rid of ip_id_count Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 034/104] ip: make IP identifiers less predictable Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 035/104] net: sendmsg: fix NULL pointer dereference Jiri Slaby
2014-08-20 11:42 ` [PATCH 3.12 036/104] tcp: Fix integer-overflows in TCP veno Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 037/104] tcp: Fix integer-overflow in TCP vegas Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 038/104] net: sctp: inherit auth_capable on INIT collisions Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 039/104] macvlan: Initialize vlan_features to turn on offload support Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 040/104] net: Correctly set segment mac_len in skb_segment() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 041/104] iovec: make sure the caller actually wants anything in memcpy_fromiovecend Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 042/104] sctp: fix possible seqlock seadlock in sctp_packet_transmit() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 043/104] sparc64: Fix argument sign extension for compat_sys_futex() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 044/104] sparc64: Make itc_sync_lock raw Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 045/104] sparc64: Fix executable bit testing in set_pmd_at() paths Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 046/104] sparc64: Handle 32-bit tasks properly in compute_effective_address() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 047/104] sparc64: Fix top-level fault handling bugs Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 048/104] sparc64: Add basic validations to {pud,pmd}_bad() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 049/104] sparc64: Give more detailed information in {pgd,pmd}_ERROR() and kill pte_ERROR() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 050/104] sparc64: Don't bark so loudly about 32-bit tasks generating 64-bit fault addresses Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 051/104] sparc64: Fix huge TSB mapping on pre-UltraSPARC-III cpus Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 052/104] sparc64: Add membar to Niagara2 memcpy code Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 053/104] sparc64: Do not insert non-valid PTEs into the TSB hash table Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 054/104] sparc64: Guard against flushing openfirmware mappings Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 055/104] bbc-i2c: Fix BBC I2C envctrl on SunBlade 2000 Jiri Slaby
2014-08-20 11:43   ` Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 056/104] sunsab: Fix detection of BREAK on sunsab serial console Jiri Slaby
2014-08-20 11:43   ` Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 057/104] sparc64: ldc_connect() should not return EINVAL when handshake is in progress Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 058/104] arch/sparc/math-emu/math_32.c: drop stray break operator Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 059/104] iwlwifi: mvm: Add a missed beacons threshold Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 060/104] mac80211: reset probe_send_count also in HW_CONNECTION_MONITOR case Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 061/104] hugetlb: fix copy_hugetlb_page_range() to handle migration/hwpoisoned entry Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 062/104] mm: hugetlb: fix copy_hugetlb_page_range() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 063/104] mnt: Only change user settable mount flags in remount Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 064/104] mnt: Move the test for MNT_LOCK_READONLY from change_mount_flags into do_remount Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 065/104] mnt: Correct permission checks in do_remount Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 066/104] ext4: Fix block zeroing when punching holes in indirect block files Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 067/104] offb: Little endian fixes Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 068/104] fbcon: Clean up fbcon data in fb_info on FB_EVENT_FB_UNBIND with 0 fbs Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 069/104] DMA-API: provide a helper to set both DMA and coherent DMA masks Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 070/104] DMA-API: net: intel/e1000e: fix 32-bit DMA mask handling Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 071/104] e1000e: Fix a compile flag mis-match for suspend/resume Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 072/104] e1000e: Fix compilation warning when !CONFIG_PM_SLEEP Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 073/104] e1000: fix wrong queue idx calculation Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 074/104] e1000: prevent oops when adapter is being closed and reset simultaneously Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 075/104] e1000: fix possible reset_task running after adapter down Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 076/104] DMA-API: net: intel/ixgbe: fix 32-bit DMA mask handling Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 077/104] ixgbe: fix rx-usecs range checks for BQL Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 078/104] ixgbe: fix qv_lock_napi call in ixgbe_napi_disable_all Jiri Slaby
2014-08-21 10:03   ` Eliezer Tamir
2014-08-21 14:55     ` Keller, Jacob E
2014-08-21 14:55       ` Keller, Jacob E
2014-08-20 11:43 ` [PATCH 3.12 079/104] ixgbe: fix inconsistent clearing of the multicast table Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 080/104] DMA-API: net: intel/ixgbevf: fix 32-bit DMA mask handling Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 081/104] ixgbevf: cleanup redundant mailbox read failure check Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 082/104] DMA-API: net: intel/igb: fix 32-bit DMA mask handling Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 083/104] igb: Add ethtool offline tests for i354 Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 084/104] igb: Fix master/slave mode for all m88 i354 PHY's Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 085/104] igb: fix driver reload with VF assigned to guest Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 086/104] igb: Don't let ethtool try to write to iNVM in i210/i211 Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 087/104] igb: Fixed Wake On LAN support Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 088/104] DMA-API: net: intel/igbvf: fix 32-bit DMA mask handling Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 089/104] igbvf: integer wrapping bug setting the mtu Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 090/104] igbvf: add missing iounmap() on error in igbvf_probe() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 091/104] DMA-API: net: brocade/bna/bnad.c: fix 32-bit DMA mask handling Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 092/104] netxen: Correct off-by-one errors in bounds checks Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 093/104] RDMA/cxgb3: Fix information leak in send_abort() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 094/104] bnx2x: Test nvram when interface is down Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 095/104] bnx2fc: fix memory leak in bnx2fc_allocate_hash_table() Jiri Slaby
2014-08-20 11:43 ` [PATCH 3.12 096/104] tg3: Add support for new 577xx device ids Jiri Slaby
2014-08-20 11:44 ` [PATCH 3.12 097/104] tipc: don't use memcpy to copy from user space Jiri Slaby
2014-08-20 11:44 ` [PATCH 3.12 098/104] PCI: rphahp: Fix endianess issues Jiri Slaby
2014-08-20 11:44 ` [PATCH 3.12 099/104] Input: i8042 - add Acer Aspire 5710 to nomux blacklist Jiri Slaby
2014-08-20 11:44 ` [PATCH 3.12 100/104] HID: logitech-dj: Fix USB 3.0 issue Jiri Slaby
2014-08-20 11:44 ` [PATCH 3.12 101/104] ALSA: hda - load EQ params into IDT codec on HP bNB13 systems Jiri Slaby
2014-08-20 11:44 ` [PATCH 3.12 102/104] drivers/rtc/rtc-efi.c: avoid subtracting day twice when computing year days Jiri Slaby
2014-08-20 11:44 ` [PATCH 3.12 103/104] drivers/rtc/rtc-efi.c: check for invalid data coming back from UEFI Jiri Slaby
2014-08-20 11:44 ` [PATCH 3.12 104/104] drivers/rtc/interface.c: fix infinite loop in initializing the alarm Jiri Slaby
2014-08-20 16:54 ` [PATCH 3.12 000/104] 3.12.27-stable review Guenter Roeck
2014-08-20 19:54   ` Guenter Roeck
2014-08-21  8:05     ` Jiri Slaby
2014-08-21 15:08       ` Guenter Roeck
2014-08-21 16:31       ` Guenter Roeck
2014-08-23 15:14       ` Guenter Roeck
2014-08-23 18:10         ` David Miller
2014-08-26 11:32           ` Jiri Slaby
2014-08-22 19:38 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7e329475de1f97df56e1cfa412e5b3479994c202.1408535000.git.jslaby@suse.cz \
    --to=jslaby@suse.cz \
    --cc=amluto@gmail.com \
    --cc=arjan.van.de.ven@intel.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=bp@alien8.de \
    --cc=comexk@gmail.com \
    --cc=dirk@hohndel.org \
    --cc=heukelum@fastmail.fm \
    --cc=hpa@linux.intel.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.