From: Thomas Gleixner <tglx@linutronix.de>

LDT entries need to be user visible. Add them to the user shared fixmaps so
they can be mapped to the actual location of the LDT entries of a process
on task switch.

Populate the PTEs upfront so the PMD sharing works.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 arch/x86/include/asm/fixmap.h |    3 +++
 arch/x86/kernel/cpu/common.c  |    2 ++
 2 files changed, 5 insertions(+)

--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -20,6 +20,7 @@
 #include <asm/apicdef.h>
 #include <asm/page.h>
 #include <asm/intel_ds.h>
+#include <asm/ldt.h>
 #ifdef CONFIG_X86_32
 #include <linux/threads.h>
 #include <asm/kmap_types.h>
@@ -91,6 +92,8 @@ struct cpu_entry_area {
 	 */
 	struct debug_store_buffers cpu_debug_buffers;
 #endif
+	/* Provide fixmap space for user LDTs */
+	char ldt_entries[LDT_ENTRIES * LDT_ENTRY_SIZE];
 };
 
 #define CPU_ENTRY_AREA_PAGES (sizeof(struct cpu_entry_area) / PAGE_SIZE)
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -613,6 +613,8 @@ static void __init setup_cpu_entry_area(
 	set_percpu_fixmap_ptes(get_cpu_entry_area_index(cpu, cpu_debug_buffers),
 			       sizeof(struct debug_store_buffers) / PAGE_SIZE);
 #endif
+	set_percpu_fixmap_ptes(get_cpu_entry_area_index(cpu, ldt_entries),
+			       (LDT_ENTRIES * LDT_ENTRY_SIZE) / PAGE_SIZE);
 }
 
 void __init setup_cpu_entry_areas(void)