Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 15 Apr 2018 20:35:29 +0000 (13:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 15 Apr 2018 20:35:29 +0000 (13:35 -0700)
Pull x86 pti updates from Thomas Gleixner:
 "Another series of PTI related changes:

   - Remove the manual stack switch for user entries from the idtentry
     code. This debloats entry by 5k+ bytes of text.

   - Use the proper types for the asm/bootparam.h defines to prevent
     user space compile errors.

   - Use PAGE_GLOBAL for !PCID systems to gain back performance

   - Prevent setting of huge PUD/PMD entries when the entries are not
     leaf entries otherwise the entries to which the PUD/PMD points to
     and are populated get lost"

* 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/pgtable: Don't set huge PUD/PMD on non-leaf entries
  x86/pti: Leave kernel text global for !PCID
  x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image
  x86/pti: Enable global pages for shared areas
  x86/mm: Do not forbid _PAGE_RW before init for __ro_after_init
  x86/mm: Comment _PAGE_GLOBAL mystery
  x86/mm: Remove extra filtering in pageattr code
  x86/mm: Do not auto-massage page protections
  x86/espfix: Document use of _PAGE_GLOBAL
  x86/mm: Introduce "default" kernel PTE mask
  x86/mm: Undo double _PAGE_PSE clearing
  x86/mm: Factor out pageattr _PAGE_GLOBAL setting
  x86/entry/64: Drop idtentry's manual stack switch for user entries
  x86/uapi: Fix asm/bootparam.h userspace compilation errors

1  2 
arch/x86/entry/entry_64.S
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c

index b0a4649e55ce8185d4cd0f5c8b778750ff067f90,cb1d8a3b870b97214ae60b1848556b79f4c17546..a0c1353a22664ee3f74805285f28745559e8f12d
@@@ -913,7 -913,7 +913,7 @@@ ENTRY(\sym
        pushq   $-1                             /* ORIG_RAX: no syscall to restart */
        .endif
  
-       .if \paranoid < 2
+       .if \paranoid == 1
        testb   $3, CS-ORIG_RAX(%rsp)           /* If coming from userspace, switch stacks */
        jnz     .Lfrom_usermode_switch_stack_\@
        .endif
        jmp     error_exit
        .endif
  
-       .if \paranoid < 2
+       .if \paranoid == 1
        /*
         * Entry from userspace.  Switch stacks and treat it
         * as a normal entry.  This means that paranoid handlers
@@@ -1140,9 -1140,6 +1140,9 @@@ apicinterrupt3 HYPERVISOR_CALLBACK_VECT
  
  apicinterrupt3 HYPERV_REENLIGHTENMENT_VECTOR \
        hyperv_reenlightenment_vector hyperv_reenlightenment_intr
 +
 +apicinterrupt3 HYPERV_STIMER0_VECTOR \
 +      hv_stimer0_callback_vector hv_stimer0_vector_handler
  #endif /* CONFIG_HYPERV */
  
  idtentry debug                        do_debug                has_error_code=0        paranoid=1 shift_ist=DEBUG_STACK
diff --combined arch/x86/mm/init_32.c
index 8008db2bddb36aaa071065dc273a8d2a65adc34a,07cdc2ed4965924d355eb9f17b2ec1d3efe7cda1..c893c6a3d7079cf1210ad9562644ec8eb240d1d7
@@@ -558,8 -558,14 +558,14 @@@ static void __init pagetable_init(void
        permanent_kmaps_init(pgd_base);
  }
  
- pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL);
+ #define DEFAULT_PTE_MASK ~(_PAGE_NX | _PAGE_GLOBAL)
+ /* Bits supported by the hardware: */
+ pteval_t __supported_pte_mask __read_mostly = DEFAULT_PTE_MASK;
+ /* Bits allowed in normal kernel mappings: */
+ pteval_t __default_kernel_pte_mask __read_mostly = DEFAULT_PTE_MASK;
  EXPORT_SYMBOL_GPL(__supported_pte_mask);
+ /* Used in PAGE_KERNEL_* macros which are reasonably used out-of-tree: */
+ EXPORT_SYMBOL(__default_kernel_pte_mask);
  
  /* user-defined highmem size */
  static unsigned int highmem_pages = -1;
@@@ -778,7 -784,6 +784,7 @@@ void __init mem_init(void
        free_all_bootmem();
  
        after_bootmem = 1;
 +      x86_init.hyper.init_after_bootmem();
  
        mem_init_print_info(NULL);
        printk(KERN_INFO "virtual kernel memory layout:\n"
diff --combined arch/x86/mm/init_64.c
index 66de40e45f5877e234a044ae565ab9bcdf0ae4a0,6d1ff39c24382f1a474054b954fbfbcae16b6bef..0a400606dea006c5faa8fe782135f384c180f499
   * around without checking the pgd every time.
   */
  
+ /* Bits supported by the hardware: */
  pteval_t __supported_pte_mask __read_mostly = ~0;
+ /* Bits allowed in normal kernel mappings: */
+ pteval_t __default_kernel_pte_mask __read_mostly = ~0;
  EXPORT_SYMBOL_GPL(__supported_pte_mask);
+ /* Used in PAGE_KERNEL_* macros which are reasonably used out-of-tree: */
+ EXPORT_SYMBOL(__default_kernel_pte_mask);
  
  int force_personality32;
  
@@@ -1185,7 -1190,6 +1190,7 @@@ void __init mem_init(void
        /* this will put all memory onto the freelists */
        free_all_bootmem();
        after_bootmem = 1;
 +      x86_init.hyper.init_after_bootmem();
  
        /*
         * Must be done after boot memory is put on freelist, because here we
@@@ -1286,6 -1290,12 +1291,12 @@@ void mark_rodata_ro(void
                        (unsigned long) __va(__pa_symbol(_sdata)));
  
        debug_checkwx();
+       /*
+        * Do this after all of the manipulation of the
+        * kernel text page tables are complete.
+        */
+       pti_clone_kernel_text();
  }
  
  int kern_addr_valid(unsigned long addr)
        return pfn_valid(pte_pfn(*pte));
  }
  
 +/*
 + * Block size is the minimum amount of memory which can be hotplugged or
 + * hotremoved. It must be power of two and must be equal or larger than
 + * MIN_MEMORY_BLOCK_SIZE.
 + */
 +#define MAX_BLOCK_SIZE (2UL << 30)
 +
 +/* Amount of ram needed to start using large blocks */
 +#define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30)
 +
  static unsigned long probe_memory_block_size(void)
  {
 -      unsigned long bz = MIN_MEMORY_BLOCK_SIZE;
 +      unsigned long boot_mem_end = max_pfn << PAGE_SHIFT;
 +      unsigned long bz;
  
 -      /* if system is UV or has 64GB of RAM or more, use large blocks */
 -      if (is_uv_system() || ((max_pfn << PAGE_SHIFT) >= (64UL << 30)))
 -              bz = 2UL << 30; /* 2GB */
 +      /* If this is UV system, always set 2G block size */
 +      if (is_uv_system()) {
 +              bz = MAX_BLOCK_SIZE;
 +              goto done;
 +      }
  
 +      /* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */
 +      if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) {
 +              bz = MIN_MEMORY_BLOCK_SIZE;
 +              goto done;
 +      }
 +
 +      /* Find the largest allowed block size that aligns to memory end */
 +      for (bz = MAX_BLOCK_SIZE; bz > MIN_MEMORY_BLOCK_SIZE; bz >>= 1) {
 +              if (IS_ALIGNED(boot_mem_end, bz))
 +                      break;
 +      }
 +done:
        pr_info("x86/mm: Memory block size: %ldMB\n", bz >> 20);
  
        return bz;