Merge tag 'powerpc-5.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 Nov 2019 22:35:43 +0000 (14:35 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 Nov 2019 22:35:43 +0000 (14:35 -0800)
Pull powerpc updates from Michael Ellerman:
 "Highlights:

   - Infrastructure for secure boot on some bare metal Power9 machines.
     The firmware support is still in development, so the code here
     won't actually activate secure boot on any existing systems.

   - A change to xmon (our crash handler / pseudo-debugger) to restrict
     it to read-only mode when the kernel is lockdown'ed, otherwise it's
     trivial to drop into xmon and modify kernel data, such as the
     lockdown state.

   - Support for KASLR on 32-bit BookE machines (Freescale / NXP).

   - Fixes for our flush_icache_range() and __kernel_sync_dicache()
     (VDSO) to work with memory ranges >4GB.

   - Some reworks of the pseries CMM (Cooperative Memory Management)
     driver to make it behave more like other balloon drivers and enable
     some cleanups of generic mm code.

   - A series of fixes to our hardware breakpoint support to properly
     handle unaligned watchpoint addresses.

  Plus a bunch of other smaller improvements, fixes and cleanups.

  Thanks to: Alastair D'Silva, Andrew Donnellan, Aneesh Kumar K.V,
  Anthony Steinhauser, Cédric Le Goater, Chris Packham, Chris Smart,
  Christophe Leroy, Christopher M. Riedl, Christoph Hellwig, Claudio
  Carvalho, Daniel Axtens, David Hildenbrand, Deb McLemore, Diana
  Craciun, Eric Richter, Geert Uytterhoeven, Greg Kroah-Hartman, Greg
  Kurz, Gustavo L. F. Walbon, Hari Bathini, Harish, Jason Yan, Krzysztof
  Kozlowski, Leonardo Bras, Mathieu Malaterre, Mauro S. M. Rodrigues,
  Michal Suchanek, Mimi Zohar, Nathan Chancellor, Nathan Lynch, Nayna
  Jain, Nick Desaulniers, Oliver O'Halloran, Qian Cai, Rasmus Villemoes,
  Ravi Bangoria, Sam Bobroff, Santosh Sivaraj, Scott Wood, Thomas Huth,
  Tyrel Datwyler, Vaibhav Jain, Valentin Longchamp, YueHaibing"

* tag 'powerpc-5.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (144 commits)
  powerpc/fixmap: fix crash with HIGHMEM
  x86/efi: remove unused variables
  powerpc: Define arch_is_kernel_initmem_freed() for lockdep
  powerpc/prom_init: Use -ffreestanding to avoid a reference to bcmp
  powerpc: Avoid clang warnings around setjmp and longjmp
  powerpc: Don't add -mabi= flags when building with Clang
  powerpc: Fix Kconfig indentation
  powerpc/fixmap: don't clear fixmap area in paging_init()
  selftests/powerpc: spectre_v2 test must be built 64-bit
  powerpc/powernv: Disable native PCIe port management
  powerpc/kexec: Move kexec files into a dedicated subdir.
  powerpc/32: Split kexec low level code out of misc_32.S
  powerpc/sysdev: drop simple gpio
  powerpc/83xx: map IMMR with a BAT.
  powerpc/32s: automatically allocate BAT in setbat()
  powerpc/ioremap: warn on early use of ioremap()
  powerpc: Add support for GENERIC_EARLY_IOREMAP
  powerpc/fixmap: Use __fix_to_virt() instead of fix_to_virt()
  powerpc/8xx: use the fixmapped IMMR in cpm_reset()
  powerpc/8xx: add __init to cpm1 init functions
  ...

1  2 
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/security_features.h
arch/powerpc/kernel/security.c
arch/powerpc/kernel/time.c
arch/powerpc/mm/mem.c
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/pseries/lpar.c
include/linux/security.h
security/lockdown/lockdown.c

@@@ -325,8 -325,24 +325,15 @@@ void arch_free_page(struct page *page, 
  
  struct vm_area_struct;
  
+ extern unsigned long kernstart_virt_addr;
+ static inline unsigned long kaslr_offset(void)
+ {
+       return kernstart_virt_addr - KERNELBASE;
+ }
  #include <asm-generic/memory_model.h>
  #endif /* __ASSEMBLY__ */
  #include <asm/slice.h>
  
 -/*
 - * Allow 30-bit DMA for very limited Broadcom wifi chips on many powerbooks.
 - */
 -#ifdef CONFIG_PPC32
 -#define ARCH_ZONE_DMA_BITS 30
 -#else
 -#define ARCH_ZONE_DMA_BITS 31
 -#endif
 -
  #endif /* _ASM_POWERPC_PAGE_H */
@@@ -25,9 -25,7 +25,7 @@@
  #include <asm/reg_fsl_emb.h>
  #endif
  
- #ifdef CONFIG_PPC_8xx
  #include <asm/reg_8xx.h>
- #endif /* CONFIG_PPC_8xx */
  
  #define MSR_SF_LG     63              /* Enable 64 bit mode */
  #define MSR_ISF_LG    61              /* Interrupt 64b mode valid on 630 */
  #define SPRN_USPRG7   0x107   /* SPRG7 userspace read */
  #define SPRN_SRR0     0x01A   /* Save/Restore Register 0 */
  #define SPRN_SRR1     0x01B   /* Save/Restore Register 1 */
 +
 +#ifdef CONFIG_PPC_BOOK3S
 +/*
 + * Bits loaded from MSR upon interrupt.
 + * PPC (64-bit) bits 33-36,42-47 are interrupt dependent, the others are
 + * loaded from MSR. The exception is that SRESET and MCE do not always load
 + * bit 62 (RI) from MSR. Don't use PPC_BITMASK for this because 32-bit uses
 + * it.
 + */
 +#define   SRR1_MSR_BITS               (~0x783f0000UL)
 +#endif
 +
  #define   SRR1_ISI_NOPT               0x40000000 /* ISI: Not found in hash */
  #define   SRR1_ISI_N_OR_G     0x10000000 /* ISI: Access is no-exec or G */
  #define   SRR1_ISI_PROT               0x08000000 /* ISI: Other protection fault */
@@@ -1382,6 -1368,14 +1380,14 @@@ static inline void mtmsr_isync(unsigne
  #define wrtspr(rn)    asm volatile("mtspr " __stringify(rn) ",0" : \
                                     : : "memory")
  
+ static inline void wrtee(unsigned long val)
+ {
+       if (__builtin_constant_p(val))
+               asm volatile("wrteei %0" : : "i" ((val & MSR_EE) ? 1 : 0) : "memory");
+       else
+               asm volatile("wrtee %0" : : "r" (val) : "memory");
+ }
  extern unsigned long msr_check_and_set(unsigned long bits);
  extern bool strict_msr_control;
  extern void __msr_check_and_clear(unsigned long bits);
@@@ -1396,19 -1390,9 +1402,9 @@@ static inline void msr_check_and_clear(
  #define mftb()                ({unsigned long rval;                           \
                        asm volatile(                                   \
                                "90:    mfspr %0, %2;\n"                \
-                               "97:    cmpwi %0,0;\n"                  \
-                               "       beq- 90b;\n"                    \
-                               "99:\n"                                 \
-                               ".section __ftr_fixup,\"a\"\n"          \
-                               ".align 3\n"                            \
-                               "98:\n"                                 \
-                               "       .8byte %1\n"                    \
-                               "       .8byte %1\n"                    \
-                               "       .8byte 97b-98b\n"               \
-                               "       .8byte 99b-98b\n"               \
-                               "       .8byte 0\n"                     \
-                               "       .8byte 0\n"                     \
-                               ".previous"                             \
+                               ASM_FTR_IFSET(                          \
+                                       "97:    cmpwi %0,0;\n"          \
+                                       "       beq- 90b;\n", "", %1)   \
                        : "=r" (rval) \
                        : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \
                        rval;})
@@@ -9,7 -9,7 +9,7 @@@
  #define _ASM_POWERPC_SECURITY_FEATURES_H
  
  
- extern unsigned long powerpc_security_features;
+ extern u64 powerpc_security_features;
  extern bool rfi_flush;
  
  /* These are bit flags */
@@@ -24,17 -24,17 +24,17 @@@ void setup_stf_barrier(void)
  void do_stf_barrier_fixups(enum stf_barrier_type types);
  void setup_count_cache_flush(void);
  
- static inline void security_ftr_set(unsigned long feature)
+ static inline void security_ftr_set(u64 feature)
  {
        powerpc_security_features |= feature;
  }
  
- static inline void security_ftr_clear(unsigned long feature)
+ static inline void security_ftr_clear(u64 feature)
  {
        powerpc_security_features &= ~feature;
  }
  
- static inline bool security_ftr_enabled(unsigned long feature)
+ static inline bool security_ftr_enabled(u64 feature)
  {
        return !!(powerpc_security_features & feature);
  }
@@@ -81,9 -81,6 +81,9 @@@
  // Software required to flush count cache on context switch
  #define SEC_FTR_FLUSH_COUNT_CACHE     0x0000000000000400ull
  
 +// Software required to flush link stack on context switch
 +#define SEC_FTR_FLUSH_LINK_STACK      0x0000000000001000ull
 +
  
  // Features enabled by default
  #define SEC_FTR_DEFAULT \
@@@ -16,7 -16,7 +16,7 @@@
  #include <asm/setup.h>
  
  
- unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
+ u64 powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
  
  enum count_cache_flush_type {
        COUNT_CACHE_FLUSH_NONE  = 0x1,
@@@ -24,7 -24,6 +24,7 @@@
        COUNT_CACHE_FLUSH_HW    = 0x4,
  };
  static enum count_cache_flush_type count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
 +static bool link_stack_flush_enabled;
  
  bool barrier_nospec_enabled;
  static bool no_nospec;
@@@ -95,13 -94,14 +95,14 @@@ static int barrier_nospec_get(void *dat
        return 0;
  }
  
- DEFINE_SIMPLE_ATTRIBUTE(fops_barrier_nospec,
-                       barrier_nospec_get, barrier_nospec_set, "%llu\n");
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_barrier_nospec, barrier_nospec_get,
+                        barrier_nospec_set, "%llu\n");
  
  static __init int barrier_nospec_debugfs_init(void)
  {
-       debugfs_create_file("barrier_nospec", 0600, powerpc_debugfs_root, NULL,
-                           &fops_barrier_nospec);
+       debugfs_create_file_unsafe("barrier_nospec", 0600,
+                                  powerpc_debugfs_root, NULL,
+                                  &fops_barrier_nospec);
        return 0;
  }
  device_initcall(barrier_nospec_debugfs_init);
  static __init int security_feature_debugfs_init(void)
  {
        debugfs_create_x64("security_features", 0400, powerpc_debugfs_root,
-                          (u64 *)&powerpc_security_features);
+                          &powerpc_security_features);
        return 0;
  }
  device_initcall(security_feature_debugfs_init);
@@@ -142,32 -142,33 +143,33 @@@ ssize_t cpu_show_meltdown(struct devic
  
        thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
  
-       if (rfi_flush || thread_priv) {
+       if (rfi_flush) {
                struct seq_buf s;
                seq_buf_init(&s, buf, PAGE_SIZE - 1);
  
-               seq_buf_printf(&s, "Mitigation: ");
-               if (rfi_flush)
-                       seq_buf_printf(&s, "RFI Flush");
-               if (rfi_flush && thread_priv)
-                       seq_buf_printf(&s, ", ");
+               seq_buf_printf(&s, "Mitigation: RFI Flush");
                if (thread_priv)
-                       seq_buf_printf(&s, "L1D private per thread");
+                       seq_buf_printf(&s, "L1D private per thread");
  
                seq_buf_printf(&s, "\n");
  
                return s.len;
        }
  
+       if (thread_priv)
+               return sprintf(buf, "Vulnerable: L1D private per thread\n");
        if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
            !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
                return sprintf(buf, "Not affected\n");
  
        return sprintf(buf, "Vulnerable\n");
  }
+ ssize_t cpu_show_l1tf(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+       return cpu_show_meltdown(dev, attr, buf);
+ }
  #endif
  
  ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
@@@ -213,19 -214,11 +215,19 @@@ ssize_t cpu_show_spectre_v2(struct devi
  
                if (ccd)
                        seq_buf_printf(&s, "Indirect branch cache disabled");
 +
 +              if (link_stack_flush_enabled)
 +                      seq_buf_printf(&s, ", Software link stack flush");
 +
        } else if (count_cache_flush_type != COUNT_CACHE_FLUSH_NONE) {
                seq_buf_printf(&s, "Mitigation: Software count cache flush");
  
                if (count_cache_flush_type == COUNT_CACHE_FLUSH_HW)
                        seq_buf_printf(&s, " (hardware accelerated)");
 +
 +              if (link_stack_flush_enabled)
 +                      seq_buf_printf(&s, ", Software link stack flush");
 +
        } else if (btb_flush_enabled) {
                seq_buf_printf(&s, "Mitigation: Branch predictor state flush");
        } else {
@@@ -376,59 -369,30 +378,61 @@@ static int stf_barrier_get(void *data, 
        return 0;
  }
  
- DEFINE_SIMPLE_ATTRIBUTE(fops_stf_barrier, stf_barrier_get, stf_barrier_set, "%llu\n");
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_stf_barrier, stf_barrier_get, stf_barrier_set,
+                        "%llu\n");
  
  static __init int stf_barrier_debugfs_init(void)
  {
-       debugfs_create_file("stf_barrier", 0600, powerpc_debugfs_root, NULL, &fops_stf_barrier);
+       debugfs_create_file_unsafe("stf_barrier", 0600, powerpc_debugfs_root,
+                                  NULL, &fops_stf_barrier);
        return 0;
  }
  device_initcall(stf_barrier_debugfs_init);
  #endif /* CONFIG_DEBUG_FS */
  
 +static void no_count_cache_flush(void)
 +{
 +      count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
 +      pr_info("count-cache-flush: software flush disabled.\n");
 +}
 +
  static void toggle_count_cache_flush(bool enable)
  {
 -      if (!enable || !security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) {
 +      if (!security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE) &&
 +          !security_ftr_enabled(SEC_FTR_FLUSH_LINK_STACK))
 +              enable = false;
 +
 +      if (!enable) {
                patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP);
 -              count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
 -              pr_info("count-cache-flush: software flush disabled.\n");
 +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 +              patch_instruction_site(&patch__call_kvm_flush_link_stack, PPC_INST_NOP);
 +#endif
 +              pr_info("link-stack-flush: software flush disabled.\n");
 +              link_stack_flush_enabled = false;
 +              no_count_cache_flush();
                return;
        }
  
 +      // This enables the branch from _switch to flush_count_cache
        patch_branch_site(&patch__call_flush_count_cache,
                          (u64)&flush_count_cache, BRANCH_SET_LINK);
  
 +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 +      // This enables the branch from guest_exit_cont to kvm_flush_link_stack
 +      patch_branch_site(&patch__call_kvm_flush_link_stack,
 +                        (u64)&kvm_flush_link_stack, BRANCH_SET_LINK);
 +#endif
 +
 +      pr_info("link-stack-flush: software flush enabled.\n");
 +      link_stack_flush_enabled = true;
 +
 +      // If we just need to flush the link stack, patch an early return
 +      if (!security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) {
 +              patch_instruction_site(&patch__flush_link_stack_return, PPC_INST_BLR);
 +              no_count_cache_flush();
 +              return;
 +      }
 +
        if (!security_ftr_enabled(SEC_FTR_BCCTR_FLUSH_ASSIST)) {
                count_cache_flush_type = COUNT_CACHE_FLUSH_SW;
                pr_info("count-cache-flush: full software flush sequence enabled.\n");
@@@ -447,20 -411,11 +451,20 @@@ void setup_count_cache_flush(void
        if (no_spectrev2 || cpu_mitigations_off()) {
                if (security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED) ||
                    security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED))
 -                      pr_warn("Spectre v2 mitigations not under software control, can't disable\n");
 +                      pr_warn("Spectre v2 mitigations not fully under software control, can't disable\n");
  
                enable = false;
        }
  
 +      /*
 +       * There's no firmware feature flag/hypervisor bit to tell us we need to
 +       * flush the link stack on context switch. So we set it here if we see
 +       * either of the Spectre v2 mitigations that aim to protect userspace.
 +       */
 +      if (security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED) ||
 +          security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE))
 +              security_ftr_set(SEC_FTR_FLUSH_LINK_STACK);
 +
        toggle_count_cache_flush(enable);
  }
  
@@@ -491,13 -446,14 +495,14 @@@ static int count_cache_flush_get(void *
        return 0;
  }
  
- DEFINE_SIMPLE_ATTRIBUTE(fops_count_cache_flush, count_cache_flush_get,
-                       count_cache_flush_set, "%llu\n");
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_count_cache_flush, count_cache_flush_get,
+                        count_cache_flush_set, "%llu\n");
  
  static __init int count_cache_flush_debugfs_init(void)
  {
-       debugfs_create_file("count_cache_flush", 0600, powerpc_debugfs_root,
-                           NULL, &fops_count_cache_flush);
+       debugfs_create_file_unsafe("count_cache_flush", 0600,
+                                  powerpc_debugfs_root, NULL,
+                                  &fops_count_cache_flush);
        return 0;
  }
  device_initcall(count_cache_flush_debugfs_init);
@@@ -232,7 -232,7 +232,7 @@@ static u64 scan_dispatch_log(u64 stop_t
   * Accumulate stolen time by scanning the dispatch trace log.
   * Called on entry from user mode.
   */
- void accumulate_stolen_time(void)
+ void notrace accumulate_stolen_time(void)
  {
        u64 sst, ust;
        unsigned long save_irq_soft_mask = irq_soft_mask_return();
@@@ -338,7 -338,7 +338,7 @@@ static unsigned long vtime_delta(struc
        return stime;
  }
  
 -void vtime_account_system(struct task_struct *tsk)
 +void vtime_account_kernel(struct task_struct *tsk)
  {
        unsigned long stime, stime_scaled, steal_time;
        struct cpu_accounting_data *acct = get_accounting(tsk);
  #endif
        }
  }
 -EXPORT_SYMBOL_GPL(vtime_account_system);
 +EXPORT_SYMBOL_GPL(vtime_account_kernel);
  
  void vtime_account_idle(struct task_struct *tsk)
  {
@@@ -395,7 -395,7 +395,7 @@@ static void vtime_flush_scaled(struct t
  /*
   * Account the whole cputime accumulated in the paca
   * Must be called with interrupts disabled.
 - * Assumes that vtime_account_system/idle() has been called
 + * Assumes that vtime_account_kernel/idle() has been called
   * recently (i.e. since the last entry from usermode) so that
   * get_paca()->user_time_scaled is up to date.
   */
diff --combined arch/powerpc/mm/mem.c
@@@ -31,7 -31,6 +31,7 @@@
  #include <linux/slab.h>
  #include <linux/vmalloc.h>
  #include <linux/memremap.h>
 +#include <linux/dma-direct.h>
  
  #include <asm/pgalloc.h>
  #include <asm/prom.h>
@@@ -105,6 -104,27 +105,27 @@@ int __weak remove_section_mapping(unsig
        return -ENODEV;
  }
  
+ #define FLUSH_CHUNK_SIZE SZ_1G
+ /**
+  * flush_dcache_range_chunked(): Write any modified data cache blocks out to
+  * memory and invalidate them, in chunks of up to FLUSH_CHUNK_SIZE
+  * Does not invalidate the corresponding instruction cache blocks.
+  *
+  * @start: the start address
+  * @stop: the stop address (exclusive)
+  * @chunk: the max size of the chunks
+  */
+ static void flush_dcache_range_chunked(unsigned long start, unsigned long stop,
+                                      unsigned long chunk)
+ {
+       unsigned long i;
+       for (i = start; i < stop; i += chunk) {
+               flush_dcache_range(i, min(stop, start + chunk));
+               cond_resched();
+       }
+ }
  int __ref arch_add_memory(int nid, u64 start, u64 size,
                        struct mhp_restrictions *restrictions)
  {
                        start, start + size, rc);
                return -EFAULT;
        }
-       flush_dcache_range(start, start + size);
  
        return __add_pages(nid, start_pfn, nr_pages, restrictions);
  }
@@@ -138,7 -157,8 +158,8 @@@ void __ref arch_remove_memory(int nid, 
  
        /* Remove htab bolted mappings for this section of memory */
        start = (unsigned long)__va(start);
-       flush_dcache_range(start, start + size);
+       flush_dcache_range_chunked(start, start + size, FLUSH_CHUNK_SIZE);
        ret = remove_section_mapping(start, start + size);
        WARN_ON_ONCE(ret);
  
@@@ -202,10 -222,10 +223,10 @@@ static int __init mark_nonram_nosave(vo
   * everything else. GFP_DMA32 page allocations automatically fall back to
   * ZONE_DMA.
   *
 - * By using 31-bit unconditionally, we can exploit ARCH_ZONE_DMA_BITS to
 - * inform the generic DMA mapping code.  32-bit only devices (if not handled
 - * by an IOMMU anyway) will take a first dip into ZONE_NORMAL and get
 - * otherwise served by ZONE_DMA.
 + * By using 31-bit unconditionally, we can exploit zone_dma_bits to inform the
 + * generic DMA mapping code.  32-bit only devices (if not handled by an IOMMU
 + * anyway) will take a first dip into ZONE_NORMAL and get otherwise served by
 + * ZONE_DMA.
   */
  static unsigned long max_zone_pfns[MAX_NR_ZONES];
  
@@@ -217,15 -237,13 +238,13 @@@ void __init paging_init(void
        unsigned long long total_ram = memblock_phys_mem_size();
        phys_addr_t top_of_ram = memblock_end_of_DRAM();
  
- #ifdef CONFIG_PPC32
-       unsigned long v = __fix_to_virt(__end_of_fixed_addresses - 1);
-       unsigned long end = __fix_to_virt(FIX_HOLE);
+ #ifdef CONFIG_HIGHMEM
+       unsigned long v = __fix_to_virt(FIX_KMAP_END);
+       unsigned long end = __fix_to_virt(FIX_KMAP_BEGIN);
  
        for (; v < end; v += PAGE_SIZE)
                map_kernel_page(v, 0, __pgprot(0)); /* XXX gross */
- #endif
  
- #ifdef CONFIG_HIGHMEM
        map_kernel_page(PKMAP_BASE, 0, __pgprot(0));    /* XXX gross */
        pkmap_page_table = virt_to_kpte(PKMAP_BASE);
  
        printk(KERN_DEBUG "Memory hole size: %ldMB\n",
               (long int)((top_of_ram - total_ram) >> 20));
  
 +      /*
 +       * Allow 30-bit DMA for very limited Broadcom wifi chips on many
 +       * powerbooks.
 +       */
 +      if (IS_ENABLED(CONFIG_PPC32))
 +              zone_dma_bits = 30;
 +      else
 +              zone_dma_bits = 31;
 +
  #ifdef CONFIG_ZONE_DMA
        max_zone_pfns[ZONE_DMA] = min(max_low_pfn,
 -                                    1UL << (ARCH_ZONE_DMA_BITS - PAGE_SHIFT));
 +                                    1UL << (zone_dma_bits - PAGE_SHIFT));
  #endif
        max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
  #ifdef CONFIG_HIGHMEM
@@@ -328,6 -337,120 +347,120 @@@ void free_initmem(void
        free_initmem_default(POISON_FREE_INITMEM);
  }
  
+ /**
+  * flush_coherent_icache() - if a CPU has a coherent icache, flush it
+  * @addr: The base address to use (can be any valid address, the whole cache will be flushed)
+  * Return true if the cache was flushed, false otherwise
+  */
+ static inline bool flush_coherent_icache(unsigned long addr)
+ {
+       /*
+        * For a snooping icache, we still need a dummy icbi to purge all the
+        * prefetched instructions from the ifetch buffers. We also need a sync
+        * before the icbi to order the the actual stores to memory that might
+        * have modified instructions with the icbi.
+        */
+       if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
+               mb(); /* sync */
+               icbi((void *)addr);
+               mb(); /* sync */
+               isync();
+               return true;
+       }
+       return false;
+ }
+ /**
+  * invalidate_icache_range() - Flush the icache by issuing icbi across an address range
+  * @start: the start address
+  * @stop: the stop address (exclusive)
+  */
+ static void invalidate_icache_range(unsigned long start, unsigned long stop)
+ {
+       unsigned long shift = l1_icache_shift();
+       unsigned long bytes = l1_icache_bytes();
+       char *addr = (char *)(start & ~(bytes - 1));
+       unsigned long size = stop - (unsigned long)addr + (bytes - 1);
+       unsigned long i;
+       for (i = 0; i < size >> shift; i++, addr += bytes)
+               icbi(addr);
+       mb(); /* sync */
+       isync();
+ }
+ /**
+  * flush_icache_range: Write any modified data cache blocks out to memory
+  * and invalidate the corresponding blocks in the instruction cache
+  *
+  * Generic code will call this after writing memory, before executing from it.
+  *
+  * @start: the start address
+  * @stop: the stop address (exclusive)
+  */
+ void flush_icache_range(unsigned long start, unsigned long stop)
+ {
+       if (flush_coherent_icache(start))
+               return;
+       clean_dcache_range(start, stop);
+       if (IS_ENABLED(CONFIG_44x)) {
+               /*
+                * Flash invalidate on 44x because we are passed kmapped
+                * addresses and this doesn't work for userspace pages due to
+                * the virtually tagged icache.
+                */
+               iccci((void *)start);
+               mb(); /* sync */
+               isync();
+       } else
+               invalidate_icache_range(start, stop);
+ }
+ EXPORT_SYMBOL(flush_icache_range);
+ #if !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC64)
+ /**
+  * flush_dcache_icache_phys() - Flush a page by it's physical address
+  * @physaddr: the physical address of the page
+  */
+ static void flush_dcache_icache_phys(unsigned long physaddr)
+ {
+       unsigned long bytes = l1_dcache_bytes();
+       unsigned long nb = PAGE_SIZE / bytes;
+       unsigned long addr = physaddr & PAGE_MASK;
+       unsigned long msr, msr0;
+       unsigned long loop1 = addr, loop2 = addr;
+       msr0 = mfmsr();
+       msr = msr0 & ~MSR_DR;
+       /*
+        * This must remain as ASM to prevent potential memory accesses
+        * while the data MMU is disabled
+        */
+       asm volatile(
+               "   mtctr %2;\n"
+               "   mtmsr %3;\n"
+               "   isync;\n"
+               "0: dcbst   0, %0;\n"
+               "   addi    %0, %0, %4;\n"
+               "   bdnz    0b;\n"
+               "   sync;\n"
+               "   mtctr %2;\n"
+               "1: icbi    0, %1;\n"
+               "   addi    %1, %1, %4;\n"
+               "   bdnz    1b;\n"
+               "   sync;\n"
+               "   mtmsr %5;\n"
+               "   isync;\n"
+               : "+&r" (loop1), "+&r" (loop2)
+               : "r" (nb), "r" (msr), "i" (bytes), "r" (msr0)
+               : "ctr", "memory");
+ }
+ #endif // !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC64)
  /*
   * This is called when a page has been modified by the kernel.
   * It just marks the page as not i-cache clean.  We do the i-cache
@@@ -360,12 -483,46 +493,46 @@@ void flush_dcache_icache_page(struct pa
                __flush_dcache_icache(start);
                kunmap_atomic(start);
        } else {
-               __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
+               unsigned long addr = page_to_pfn(page) << PAGE_SHIFT;
+               if (flush_coherent_icache(addr))
+                       return;
+               flush_dcache_icache_phys(addr);
        }
  #endif
  }
  EXPORT_SYMBOL(flush_dcache_icache_page);
  
+ /**
+  * __flush_dcache_icache(): Flush a particular page from the data cache to RAM.
+  * Note: this is necessary because the instruction cache does *not*
+  * snoop from the data cache.
+  *
+  * @page: the address of the page to flush
+  */
+ void __flush_dcache_icache(void *p)
+ {
+       unsigned long addr = (unsigned long)p;
+       if (flush_coherent_icache(addr))
+               return;
+       clean_dcache_range(addr, addr + PAGE_SIZE);
+       /*
+        * We don't flush the icache on 44x. Those have a virtual icache and we
+        * don't have access to the virtual address here (it's not the page
+        * vaddr but where it's mapped in user space). The flushing of the
+        * icache on these is handled elsewhere, when a change in the address
+        * space occurs, before returning to user space.
+        */
+       if (cpu_has_feature(MMU_FTR_TYPE_44x))
+               return;
+       invalidate_icache_range(addr, addr + PAGE_SIZE);
+ }
  void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
  {
        clear_page(page);
@@@ -415,13 -415,13 +415,13 @@@ config PPC_MM_SLICE
        bool
  
  config PPC_HAVE_PMU_SUPPORT
-        bool
+       bool
  
  config PPC_PERF_CTRS
-        def_bool y
-        depends on PERF_EVENTS && PPC_HAVE_PMU_SUPPORT
-        help
-          This enables the powerpc-specific perf_event back-end.
+       def_bool y
+       depends on PERF_EVENTS && PPC_HAVE_PMU_SUPPORT
+       help
+        This enables the powerpc-specific perf_event back-end.
  
  config FORCE_SMP
        # Allow platforms to force SMP=y by selecting this
@@@ -459,6 -459,7 +459,6 @@@ config NOT_COHERENT_CACH
        bool
        depends on 4xx || PPC_8xx || E200 || PPC_MPC512x || \
                GAMECUBE_COMMON || AMIGAONE
 -      select ARCH_HAS_DMA_COHERENT_TO_PFN
        select ARCH_HAS_DMA_PREP_COHERENT
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE
        select ARCH_HAS_SYNC_DMA_FOR_CPU
@@@ -774,7 -774,7 +774,7 @@@ static long pSeries_lpar_hpte_remove(un
  
                /* don't remove a bolted entry */
                lpar_rc = plpar_pte_remove(H_ANDCOND, hpte_group + slot_offset,
-                                          (0x1UL << 4), &dummy1, &dummy2);
+                                          HPTE_V_BOLTED, &dummy1, &dummy2);
                if (lpar_rc == H_SUCCESS)
                        return i;
  
@@@ -938,11 -938,19 +938,19 @@@ static long pSeries_lpar_hpte_find(unsi
        hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
        want_v = hpte_encode_avpn(vpn, psize, ssize);
  
-       /* Bolted entries are always in the primary group */
+       /*
+        * We try to keep bolted entries always in primary hash
+        * But in some case we can find them in secondary too.
+        */
        hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP;
        slot = __pSeries_lpar_hpte_find(want_v, hpte_group);
-       if (slot < 0)
-               return -1;
+       if (slot < 0) {
+               /* Try in secondary */
+               hpte_group = (~hash & htab_hash_mask) * HPTES_PER_GROUP;
+               slot = __pSeries_lpar_hpte_find(want_v, hpte_group);
+               if (slot < 0)
+                       return -1;
+       }
        return hpte_group + slot;
  }
  
@@@ -1992,17 -2000,30 +2000,17 @@@ static int __init vpa_debugfs_init(void
  {
        char name[16];
        long i;
-       static struct dentry *vpa_dir;
+       struct dentry *vpa_dir;
  
        if (!firmware_has_feature(FW_FEATURE_SPLPAR))
                return 0;
  
        vpa_dir = debugfs_create_dir("vpa", powerpc_debugfs_root);
 -      if (!vpa_dir) {
 -              pr_warn("%s: can't create vpa root dir\n", __func__);
 -              return -ENOMEM;
 -      }
  
        /* set up the per-cpu vpa file*/
        for_each_possible_cpu(i) {
 -              struct dentry *d;
 -
                sprintf(name, "cpu-%ld", i);
 -
 -              d = debugfs_create_file(name, 0400, vpa_dir, (void *)i,
 -                                      &vpa_fops);
 -              if (!d) {
 -                      pr_warn("%s: can't create per-cpu vpa file\n",
 -                                      __func__);
 -                      return -ENOMEM;
 -              }
 +              debugfs_create_file(name, 0400, vpa_dir, (void *)i, &vpa_fops);
        }
  
        return 0;
diff --combined include/linux/security.h
@@@ -105,7 -105,6 +105,7 @@@ enum lockdown_reason 
        LOCKDOWN_NONE,
        LOCKDOWN_MODULE_SIGNATURE,
        LOCKDOWN_DEV_MEM,
 +      LOCKDOWN_EFI_TEST,
        LOCKDOWN_KEXEC,
        LOCKDOWN_HIBERNATION,
        LOCKDOWN_PCI_ACCESS,
        LOCKDOWN_MODULE_PARAMETERS,
        LOCKDOWN_MMIOTRACE,
        LOCKDOWN_DEBUGFS,
+       LOCKDOWN_XMON_WR,
        LOCKDOWN_INTEGRITY_MAX,
        LOCKDOWN_KCORE,
        LOCKDOWN_KPROBES,
        LOCKDOWN_BPF_READ,
        LOCKDOWN_PERF,
        LOCKDOWN_TRACEFS,
+       LOCKDOWN_XMON_RW,
        LOCKDOWN_CONFIDENTIALITY_MAX,
  };
  
@@@ -1895,42 -1896,5 +1897,42 @@@ static inline void security_bpf_prog_fr
  #endif /* CONFIG_SECURITY */
  #endif /* CONFIG_BPF_SYSCALL */
  
 -#endif /* ! __LINUX_SECURITY_H */
 +#ifdef CONFIG_PERF_EVENTS
 +struct perf_event_attr;
 +struct perf_event;
 +
 +#ifdef CONFIG_SECURITY
 +extern int security_perf_event_open(struct perf_event_attr *attr, int type);
 +extern int security_perf_event_alloc(struct perf_event *event);
 +extern void security_perf_event_free(struct perf_event *event);
 +extern int security_perf_event_read(struct perf_event *event);
 +extern int security_perf_event_write(struct perf_event *event);
 +#else
 +static inline int security_perf_event_open(struct perf_event_attr *attr,
 +                                         int type)
 +{
 +      return 0;
 +}
 +
 +static inline int security_perf_event_alloc(struct perf_event *event)
 +{
 +      return 0;
 +}
 +
 +static inline void security_perf_event_free(struct perf_event *event)
 +{
 +}
 +
 +static inline int security_perf_event_read(struct perf_event *event)
 +{
 +      return 0;
 +}
  
 +static inline int security_perf_event_write(struct perf_event *event)
 +{
 +      return 0;
 +}
 +#endif /* CONFIG_SECURITY */
 +#endif /* CONFIG_PERF_EVENTS */
 +
 +#endif /* ! __LINUX_SECURITY_H */
@@@ -20,7 -20,6 +20,7 @@@ static const char *const lockdown_reaso
        [LOCKDOWN_NONE] = "none",
        [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading",
        [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port",
 +      [LOCKDOWN_EFI_TEST] = "/dev/efi_test access",
        [LOCKDOWN_KEXEC] = "kexec of unsigned images",
        [LOCKDOWN_HIBERNATION] = "hibernation",
        [LOCKDOWN_PCI_ACCESS] = "direct PCI access",
        [LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters",
        [LOCKDOWN_MMIOTRACE] = "unsafe mmio",
        [LOCKDOWN_DEBUGFS] = "debugfs access",
+       [LOCKDOWN_XMON_WR] = "xmon write access",
        [LOCKDOWN_INTEGRITY_MAX] = "integrity",
        [LOCKDOWN_KCORE] = "/proc/kcore access",
        [LOCKDOWN_KPROBES] = "use of kprobes",
        [LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM",
        [LOCKDOWN_PERF] = "unsafe use of perf",
        [LOCKDOWN_TRACEFS] = "use of tracefs",
+       [LOCKDOWN_XMON_RW] = "xmon read and write access",
        [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
  };