--- /dev/null
+From c7b7088bdbcd8c881b332221f9aad8aba5e221cb Mon Sep 17 00:00:00 2001
+From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Date: Fri, 26 Oct 2018 15:28:55 +0300
+Subject: x86/ldt: Unmap PTEs for the slot before freeing LDT pages
+
+commit a0e6e0831c516860fc7f9be1db6c081fe902ebcf upstream
+
+modify_ldt(2) leaves the old LDT mapped after switching over to the new
+one. The old LDT gets freed and the pages can be re-used.
+
+Leaving the mapping in place can have security implications. The mapping is
+present in the userspace page tables and Meltdown-like attacks can read
+these freed and possibly reused pages.
+
+It's relatively simple to fix: unmap the old LDT and flush TLB before
+freeing the old LDT memory.
+
+This further allows to avoid flushing the TLB in map_ldt_struct() as the
+slot is unmapped and flushed by unmap_ldt_struct() or has never been mapped
+at all.
+
+[ tglx: Massaged changelog and removed the needless line breaks ]
+
+Fixes: f55f0501cbf6 ("x86/pti: Put the LDT in its own PGD if PTI is on")
+Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: bp@alien8.de
+Cc: hpa@zytor.com
+Cc: dave.hansen@linux.intel.com
+Cc: luto@kernel.org
+Cc: peterz@infradead.org
+Cc: boris.ostrovsky@oracle.com
+Cc: jgross@suse.com
+Cc: bhe@redhat.com
+Cc: willy@infradead.org
+Cc: linux-mm@kvack.org
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20181026122856.66224-3-kirill.shutemov@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/ldt.c | 49 +++++++++++++++++++++++++++++++------------
+ 1 file changed, 36 insertions(+), 13 deletions(-)
+
+diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
+index 26d713ecad34..65df298d4e9e 100644
+--- a/arch/x86/kernel/ldt.c
++++ b/arch/x86/kernel/ldt.c
+@@ -103,14 +103,6 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
+ /*
+ * If PTI is enabled, this maps the LDT into the kernelmode and
+ * usermode tables for the given mm.
+- *
+- * There is no corresponding unmap function. Even if the LDT is freed, we
+- * leave the PTEs around until the slot is reused or the mm is destroyed.
+- * This is harmless: the LDT is always in ordinary memory, and no one will
+- * access the freed slot.
+- *
+- * If we wanted to unmap freed LDTs, we'd also need to do a flush to make
+- * it useful, and the flush would slow down modify_ldt().
+ */
+ static int
+ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
+@@ -119,8 +111,8 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
+ bool is_vmalloc, had_top_level_entry;
+ unsigned long va;
+ spinlock_t *ptl;
++ int i, nr_pages;
+ pgd_t *pgd;
+- int i;
+
+ if (!static_cpu_has(X86_FEATURE_PTI))
+ return 0;
+@@ -141,7 +133,9 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
+
+ is_vmalloc = is_vmalloc_addr(ldt->entries);
+
+- for (i = 0; i * PAGE_SIZE < ldt->nr_entries * LDT_ENTRY_SIZE; i++) {
++ nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE);
++
++ for (i = 0; i < nr_pages; i++) {
+ unsigned long offset = i << PAGE_SHIFT;
+ const void *src = (char *)ldt->entries + offset;
+ unsigned long pfn;
+@@ -189,14 +183,42 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
+ }
+ }
+
+- va = (unsigned long)ldt_slot_va(slot);
+- flush_tlb_mm_range(mm, va, va + LDT_SLOT_STRIDE, 0);
+-
+ ldt->slot = slot;
+ #endif
+ return 0;
+ }
+
++static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt)
++{
++#ifdef CONFIG_PAGE_TABLE_ISOLATION
++ unsigned long va;
++ int i, nr_pages;
++
++ if (!ldt)
++ return;
++
++ /* LDT map/unmap is only required for PTI */
++ if (!static_cpu_has(X86_FEATURE_PTI))
++ return;
++
++ nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE);
++
++ for (i = 0; i < nr_pages; i++) {
++ unsigned long offset = i << PAGE_SHIFT;
++ spinlock_t *ptl;
++ pte_t *ptep;
++
++ va = (unsigned long)ldt_slot_va(ldt->slot) + offset;
++ ptep = get_locked_pte(mm, va, &ptl);
++ pte_clear(mm, va, ptep);
++ pte_unmap_unlock(ptep, ptl);
++ }
++
++ va = (unsigned long)ldt_slot_va(ldt->slot);
++ flush_tlb_mm_range(mm, va, va + nr_pages * PAGE_SIZE, 0);
++#endif /* CONFIG_PAGE_TABLE_ISOLATION */
++}
++
+ static void free_ldt_pgtables(struct mm_struct *mm)
+ {
+ #ifdef CONFIG_PAGE_TABLE_ISOLATION
+@@ -433,6 +455,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
+ }
+
+ install_ldt(mm, new_ldt);
++ unmap_ldt_struct(mm, old_ldt);
+ free_ldt_struct(old_ldt);
+ error = 0;
+
+--
+2.17.1
+
--- /dev/null
+From 42e79e3915279126ad746b11ff8f3fc7a55c77ec Mon Sep 17 00:00:00 2001
+From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Date: Fri, 26 Oct 2018 15:28:54 +0300
+Subject: x86/mm: Move LDT remap out of KASLR region on 5-level paging
+
+commit d52888aa2753e3063a9d3a0c9f72f94aa9809c15 upstream
+
+On 5-level paging the LDT remap area is placed in the middle of the KASLR
+randomization region and it can overlap with the direct mapping, the
+vmalloc or the vmap area.
+
+The LDT mapping is per mm, so it cannot be moved into the P4D page table
+next to the CPU_ENTRY_AREA without complicating PGD table allocation for
+5-level paging.
+
+The 4 PGD slot gap just before the direct mapping is reserved for
+hypervisors, so it cannot be used.
+
+Move the direct mapping one slot deeper and use the resulting gap for the
+LDT remap area. The resulting layout is the same for 4 and 5 level paging.
+
+[ tglx: Massaged changelog ]
+
+Fixes: f55f0501cbf6 ("x86/pti: Put the LDT in its own PGD if PTI is on")
+Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Andy Lutomirski <luto@kernel.org>
+Cc: bp@alien8.de
+Cc: hpa@zytor.com
+Cc: dave.hansen@linux.intel.com
+Cc: peterz@infradead.org
+Cc: boris.ostrovsky@oracle.com
+Cc: jgross@suse.com
+Cc: bhe@redhat.com
+Cc: willy@infradead.org
+Cc: linux-mm@kvack.org
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20181026122856.66224-2-kirill.shutemov@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/x86/x86_64/mm.txt | 10 ++++++----
+ arch/x86/include/asm/page_64_types.h | 12 +++++++-----
+ arch/x86/include/asm/pgtable_64_types.h | 7 +++----
+ arch/x86/xen/mmu_pv.c | 6 +++---
+ 4 files changed, 19 insertions(+), 16 deletions(-)
+
+diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
+index ea91cb61a602..43f066cde67d 100644
+--- a/Documentation/x86/x86_64/mm.txt
++++ b/Documentation/x86/x86_64/mm.txt
+@@ -4,8 +4,9 @@ Virtual memory map with 4 level page tables:
+ 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
+ hole caused by [47:63] sign extension
+ ffff800000000000 - ffff87ffffffffff (=43 bits) guard hole, reserved for hypervisor
+-ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
+-ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
++ffff880000000000 - ffff887fffffffff (=39 bits) LDT remap for PTI
++ffff888000000000 - ffffc87fffffffff (=64 TB) direct mapping of all phys. memory
++ffffc88000000000 - ffffc8ffffffffff (=39 bits) hole
+ ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
+ ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
+ ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
+@@ -30,8 +31,9 @@ Virtual memory map with 5 level page tables:
+ 0000000000000000 - 00ffffffffffffff (=56 bits) user space, different per mm
+ hole caused by [56:63] sign extension
+ ff00000000000000 - ff0fffffffffffff (=52 bits) guard hole, reserved for hypervisor
+-ff10000000000000 - ff8fffffffffffff (=55 bits) direct mapping of all phys. memory
+-ff90000000000000 - ff9fffffffffffff (=52 bits) LDT remap for PTI
++ff10000000000000 - ff10ffffffffffff (=48 bits) LDT remap for PTI
++ff11000000000000 - ff90ffffffffffff (=55 bits) direct mapping of all phys. memory
++ff91000000000000 - ff9fffffffffffff (=3840 TB) hole
+ ffa0000000000000 - ffd1ffffffffffff (=54 bits) vmalloc/ioremap space (12800 TB)
+ ffd2000000000000 - ffd3ffffffffffff (=49 bits) hole
+ ffd4000000000000 - ffd5ffffffffffff (=49 bits) virtual memory map (512TB)
+diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
+index e1407312c412..74d531f6d518 100644
+--- a/arch/x86/include/asm/page_64_types.h
++++ b/arch/x86/include/asm/page_64_types.h
+@@ -33,14 +33,16 @@
+
+ /*
+ * Set __PAGE_OFFSET to the most negative possible address +
+- * PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a
+- * hypervisor to fit. Choosing 16 slots here is arbitrary, but it's
+- * what Xen requires.
++ * PGDIR_SIZE*17 (pgd slot 273).
++ *
++ * The gap is to allow a space for LDT remap for PTI (1 pgd slot) and space for
++ * a hypervisor (16 slots). Choosing 16 slots for a hypervisor is arbitrary,
++ * but it's what Xen requires.
+ */
+ #ifdef CONFIG_X86_5LEVEL
+-#define __PAGE_OFFSET_BASE _AC(0xff10000000000000, UL)
++#define __PAGE_OFFSET_BASE _AC(0xff11000000000000, UL)
+ #else
+-#define __PAGE_OFFSET_BASE _AC(0xffff880000000000, UL)
++#define __PAGE_OFFSET_BASE _AC(0xffff888000000000, UL)
+ #endif
+
+ #ifdef CONFIG_RANDOMIZE_MEMORY
+diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
+index 6b8f73dcbc2c..7764617b8f9c 100644
+--- a/arch/x86/include/asm/pgtable_64_types.h
++++ b/arch/x86/include/asm/pgtable_64_types.h
+@@ -88,16 +88,15 @@ typedef struct { pteval_t pte; } pte_t;
+ # define VMALLOC_SIZE_TB _AC(12800, UL)
+ # define __VMALLOC_BASE _AC(0xffa0000000000000, UL)
+ # define __VMEMMAP_BASE _AC(0xffd4000000000000, UL)
+-# define LDT_PGD_ENTRY _AC(-112, UL)
+-# define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT)
+ #else
+ # define VMALLOC_SIZE_TB _AC(32, UL)
+ # define __VMALLOC_BASE _AC(0xffffc90000000000, UL)
+ # define __VMEMMAP_BASE _AC(0xffffea0000000000, UL)
+-# define LDT_PGD_ENTRY _AC(-3, UL)
+-# define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT)
+ #endif
+
++#define LDT_PGD_ENTRY -240UL
++#define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT)
++
+ #ifdef CONFIG_RANDOMIZE_MEMORY
+ # define VMALLOC_START vmalloc_base
+ # define VMEMMAP_START vmemmap_base
+diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
+index 8ed11a5b1a9d..b33fa127a613 100644
+--- a/arch/x86/xen/mmu_pv.c
++++ b/arch/x86/xen/mmu_pv.c
+@@ -1869,7 +1869,7 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
+ init_top_pgt[0] = __pgd(0);
+
+ /* Pre-constructed entries are in pfn, so convert to mfn */
+- /* L4[272] -> level3_ident_pgt */
++ /* L4[273] -> level3_ident_pgt */
+ /* L4[511] -> level3_kernel_pgt */
+ convert_pfn_mfn(init_top_pgt);
+
+@@ -1889,8 +1889,8 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
+ addr[0] = (unsigned long)pgd;
+ addr[1] = (unsigned long)l3;
+ addr[2] = (unsigned long)l2;
+- /* Graft it onto L4[272][0]. Note that we creating an aliasing problem:
+- * Both L4[272][0] and L4[511][510] have entries that point to the same
++ /* Graft it onto L4[273][0]. Note that we creating an aliasing problem:
++ * Both L4[273][0] and L4[511][510] have entries that point to the same
+ * L2 (PMD) tables. Meaning that if you modify it in __va space
+ * it will be also modified in the __ka space! (But if you just
+ * modify the PMD table to point to other PTE's or none, then you
+--
+2.17.1
+