]> Git Repo - linux.git/commitdiff
Merge tag 'powerpc-5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
authorLinus Torvalds <[email protected]>
Thu, 7 Mar 2019 20:56:26 +0000 (12:56 -0800)
committerLinus Torvalds <[email protected]>
Thu, 7 Mar 2019 20:56:26 +0000 (12:56 -0800)
Pull powerpc updates from Michael Ellerman:
 "Notable changes:

   - Enable THREAD_INFO_IN_TASK to move thread_info off the stack.

   - A big series from Christoph reworking our DMA code to use more of
     the generic infrastructure, as he said:
       "This series switches the powerpc port to use the generic swiotlb
        and noncoherent dma ops, and to use more generic code for the
        coherent direct mapping, as well as removing a lot of dead
        code."

   - Increase our vmalloc space to 512T with the Hash MMU on modern
     CPUs, allowing us to support machines with larger amounts of total
     RAM or distance between nodes.

   - Two series from Christophe, one to optimise TLB miss handlers on
     6xx, and another to optimise the way STRICT_KERNEL_RWX is
     implemented on some 32-bit CPUs.

   - Support for KCOV coverage instrumentation which means we can run
     syzkaller and discover even more bugs in our code.

  And as always many clean-ups, reworks and minor fixes etc.

  Thanks to: Alan Modra, Alexey Kardashevskiy, Alistair Popple, Andrea
  Arcangeli, Andrew Donnellan, Aneesh Kumar K.V, Aravinda Prasad, Balbir
  Singh, Brajeswar Ghosh, Breno Leitao, Christian Lamparter, Christian
  Zigotzky, Christophe Leroy, Christoph Hellwig, Corentin Labbe, Daniel
  Axtens, David Gibson, Diana Craciun, Firoz Khan, Gustavo A. R. Silva,
  Igor Stoppa, Joe Lawrence, Joel Stanley, Jonathan Neuschäfer, Jordan
  Niethe, Laurent Dufour, Madhavan Srinivasan, Mahesh Salgaonkar, Mark
  Cave-Ayland, Masahiro Yamada, Mathieu Malaterre, Matteo Croce, Meelis
  Roos, Michael W. Bringmann, Nathan Chancellor, Nathan Fontenot,
  Nicholas Piggin, Nick Desaulniers, Nicolai Stange, Oliver O'Halloran,
  Paul Mackerras, Peter Xu, PrasannaKumar Muralidharan, Qian Cai,
  Rashmica Gupta, Reza Arbab, Robert P. J. Day, Russell Currey,
  Sabyasachi Gupta, Sam Bobroff, Sandipan Das, Sergey Senozhatsky,
  Souptick Joarder, Stewart Smith, Tyrel Datwyler, Vaibhav Jain,
  YueHaibing"

* tag 'powerpc-5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (200 commits)
  powerpc/32: Clear on-stack exception marker upon exception return
  powerpc: Remove export of save_stack_trace_tsk_reliable()
  powerpc/mm: fix "section_base" set but not used
  powerpc/mm: Fix "sz" set but not used warning
  powerpc/mm: Check secondary hash page table
  powerpc: remove nargs from __SYSCALL
  powerpc/64s: Fix unrelocated interrupt trampoline address test
  powerpc/powernv/ioda: Fix locked_vm counting for memory used by IOMMU tables
  powerpc/fsl: Fix the flush of branch predictor.
  powerpc/powernv: Make opal log only readable by root
  powerpc/xmon: Fix opcode being uninitialized in print_insn_powerpc
  powerpc/powernv: move OPAL call wrapper tracing and interrupt handling to C
  powerpc/64s: Fix data interrupts vs d-side MCE reentrancy
  powerpc/64s: Prepare to handle data interrupts vs d-side MCE reentrancy
  powerpc/64s: system reset interrupt preserve HSRRs
  powerpc/64s: Fix HV NMI vs HV interrupt recoverability test
  powerpc/mm/hash: Handle mmap_min_addr correctly in get_unmapped_area topdown search
  powerpc/hugetlb: Handle mmap_min_addr correctly in get_unmapped_area callback
  selftests/powerpc: Remove duplicate header
  powerpc sstep: Add support for modsd, modud instructions
  ...

1  2 
arch/powerpc/Kconfig
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/mm/hugetlbpage-hash64.c
arch/powerpc/mm/hugetlbpage-radix.c
arch/powerpc/mm/numa.c
arch/powerpc/platforms/powernv/pci-ioda.c
kernel/dma/swiotlb.c

diff --combined arch/powerpc/Kconfig
index 7deb3ea2dd3fac6335d955b5b457299807efead2,652c25260838a594f998ab2571cb685ffe72b2aa..b5dce13a61321693f466f019d22ad962481be70b
@@@ -119,22 -119,18 +119,19 @@@ config GENERIC_HWEIGH
        bool
        default y
  
- config ARCH_HAS_DMA_SET_COHERENT_MASK
-         bool
  config PPC
        bool
        default y
        #
        # Please keep this list sorted alphabetically.
        #
 +      select ARCH_32BIT_OFF_T if PPC32
        select ARCH_HAS_DEBUG_VIRTUAL
        select ARCH_HAS_DEVMEM_IS_ALLOWED
-       select ARCH_HAS_DMA_SET_COHERENT_MASK
        select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_GCOV_PROFILE_ALL
+       select ARCH_HAS_KCOV
        select ARCH_HAS_PHYS_TO_DMA
        select ARCH_HAS_PMEM_API                if PPC64
        select ARCH_HAS_PTE_SPECIAL
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_MMAP_RND_BITS
        select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
 +      select HAVE_ARCH_NVRAM_OPS
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_CBPF_JIT                    if !PPC64
        select HAVE_IOREMAP_PROT
        select HAVE_IRQ_EXIT_ON_IRQ_STACK
        select HAVE_KERNEL_GZIP
-       select HAVE_KERNEL_XZ                   if PPC_BOOK3S
+       select HAVE_KERNEL_XZ                   if PPC_BOOK3S || 44x
        select HAVE_KPROBES
        select HAVE_KPROBES_ON_FTRACE
        select HAVE_KRETPROBES
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_RCU_TABLE_FREE              if SMP
        select HAVE_REGS_AND_STACK_ACCESS_API
-       select HAVE_RELIABLE_STACKTRACE         if PPC64 && CPU_LITTLE_ENDIAN
+       select HAVE_RELIABLE_STACKTRACE         if PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_VIRT_CPU_ACCOUNTING
        select HAVE_IRQ_TIME_ACCOUNTING
        select RTC_LIB
        select SPARSE_IRQ
        select SYSCTL_EXCEPTION_TRACE
+       select THREAD_INFO_IN_TASK
        select VIRT_TO_BUS                      if !PPC64
        #
        # Please keep this list sorted alphabetically.
@@@ -253,9 -249,6 +251,6 @@@ config PPC_BARRIER_NOSPE
      default y
      depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E
  
- config GENERIC_CSUM
-       def_bool n
  config EARLY_PRINTK
        bool
        default y
@@@ -276,6 -269,11 +271,6 @@@ config SYSVIPC_COMPA
        depends on COMPAT && SYSVIPC
        default y
  
 -# All PPC32s use generic nvram driver through ppc_md
 -config GENERIC_NVRAM
 -      bool
 -      default y if PPC32
 -
  config SCHED_OMIT_FRAME_POINTER
        bool
        default y
@@@ -475,9 -473,6 +470,6 @@@ config ARCH_CPU_PROBE_RELEAS
  config ARCH_ENABLE_MEMORY_HOTPLUG
        def_bool y
  
- config ARCH_HAS_WALK_MEMORY
-       def_bool y
  config ARCH_ENABLE_MEMORY_HOTREMOVE
        def_bool y
  
@@@ -693,7 -688,7 +685,7 @@@ config PPC_16K_PAGE
  
  config PPC_64K_PAGES
        bool "64k page size"
-       depends on !PPC_FSL_BOOK3E && (44x || PPC_BOOK3S_64 || PPC_BOOK3E_64)
+       depends on 44x || PPC_BOOK3S_64
        select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64
  
  config PPC_256K_PAGES
  
  endchoice
  
+ config PPC_PAGE_SHIFT
+       int
+       default 18 if PPC_256K_PAGES
+       default 16 if PPC_64K_PAGES
+       default 14 if PPC_16K_PAGES
+       default 12
  config THREAD_SHIFT
        int "Thread shift" if EXPERT
        range 13 15
          Used to define the stack size. The default is almost always what you
          want. Only change this if you know what you are doing.
  
+ config ETEXT_SHIFT_BOOL
+       bool "Set custom etext alignment" if STRICT_KERNEL_RWX && \
+                                            (PPC_BOOK3S_32 || PPC_8xx)
+       depends on ADVANCED_OPTIONS
+       help
+         This option allows you to set the kernel end of text alignment. When
+         RAM is mapped by blocks, the alignment needs to fit the size and
+         number of possible blocks. The default should be OK for most configs.
+         Say N here unless you know what you are doing.
+ config ETEXT_SHIFT
+       int "_etext shift" if ETEXT_SHIFT_BOOL
+       range 17 28 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
+       range 19 23 if STRICT_KERNEL_RWX && PPC_8xx
+       default 17 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
+       default 19 if STRICT_KERNEL_RWX && PPC_8xx
+       default PPC_PAGE_SHIFT
+       help
+         On Book3S 32 (603+), IBATs are used to map kernel text.
+         Smaller is the alignment, greater is the number of necessary IBATs.
+         On 8xx, large pages (512kb or 8M) are used to map kernel linear
+         memory. Aligning to 8M reduces TLB misses as only 8M pages are used
+         in that case.
+ config DATA_SHIFT_BOOL
+       bool "Set custom data alignment" if STRICT_KERNEL_RWX && \
+                                           (PPC_BOOK3S_32 || PPC_8xx)
+       depends on ADVANCED_OPTIONS
+       help
+         This option allows you to set the kernel data alignment. When
+         RAM is mapped by blocks, the alignment needs to fit the size and
+         number of possible blocks. The default should be OK for most configs.
+         Say N here unless you know what you are doing.
+ config DATA_SHIFT
+       int "Data shift" if DATA_SHIFT_BOOL
+       default 24 if STRICT_KERNEL_RWX && PPC64
+       range 17 28 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
+       range 19 23 if STRICT_KERNEL_RWX && PPC_8xx
+       default 22 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
+       default 23 if STRICT_KERNEL_RWX && PPC_8xx
+       default PPC_PAGE_SHIFT
+       help
+         On Book3S 32 (603+), DBATs are used to map kernel text and rodata RO.
+         Smaller is the alignment, greater is the number of necessary DBATs.
+         On 8xx, large pages (512kb or 8M) are used to map kernel linear
+         memory. Aligning to 8M reduces TLB misses as only 8M pages are used
+         in that case.
  config FORCE_MAX_ZONEORDER
        int "Maximum zone order"
        range 8 9 if PPC64 && PPC_64K_PAGES
@@@ -887,6 -942,7 +939,7 @@@ config FSL_SO
  
  config FSL_PCI
        bool
+       select ARCH_HAS_DMA_SET_MASK
        select PPC_INDIRECT_PCI
        select PCI_QUIRKS
  
index 868fcaf56f6bf20425ae03d5fa42715cffa1c809,49c2c28882744c006f014ccb2838f36fef77be7f..581f91be9dd44735cd3626e21585fc9725d13d93
@@@ -811,7 -811,7 +811,7 @@@ static inline void __set_pte_at(struct 
        return hash__set_pte_at(mm, addr, ptep, pte, percpu);
  }
  
- #define _PAGE_CACHE_CTL       (_PAGE_NON_IDEMPOTENT | _PAGE_TOLERANT)
+ #define _PAGE_CACHE_CTL       (_PAGE_SAO | _PAGE_NON_IDEMPOTENT | _PAGE_TOLERANT)
  
  #define pgprot_noncached pgprot_noncached
  static inline pgprot_t pgprot_noncached(pgprot_t prot)
@@@ -851,11 -851,6 +851,6 @@@ static inline bool pte_ci(pte_t pte
        return false;
  }
  
- static inline void pmd_set(pmd_t *pmdp, unsigned long val)
- {
-       *pmdp = __pmd(val);
- }
  static inline void pmd_clear(pmd_t *pmdp)
  {
        *pmdp = __pmd(0);
@@@ -887,11 -882,6 +882,6 @@@ static inline int pmd_bad(pmd_t pmd
        return hash__pmd_bad(pmd);
  }
  
- static inline void pud_set(pud_t *pudp, unsigned long val)
- {
-       *pudp = __pud(val);
- }
  static inline void pud_clear(pud_t *pudp)
  {
        *pudp = __pud(0);
@@@ -934,10 -924,6 +924,6 @@@ static inline bool pud_access_permitted
  }
  
  #define pgd_write(pgd)                pte_write(pgd_pte(pgd))
- static inline void pgd_set(pgd_t *pgdp, unsigned long val)
- {
-       *pgdp = __pgd(val);
- }
  
  static inline void pgd_clear(pgd_t *pgdp)
  {
@@@ -1306,24 -1292,6 +1292,24 @@@ static inline int pud_pfn(pud_t pud
        BUILD_BUG();
        return 0;
  }
 +#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
 +pte_t ptep_modify_prot_start(struct vm_area_struct *, unsigned long, pte_t *);
 +void ptep_modify_prot_commit(struct vm_area_struct *, unsigned long,
 +                           pte_t *, pte_t, pte_t);
 +
 +/*
 + * Returns true for a R -> RW upgrade of pte
 + */
 +static inline bool is_pte_rw_upgrade(unsigned long old_val, unsigned long new_val)
 +{
 +      if (!(old_val & _PAGE_READ))
 +              return false;
 +
 +      if ((!(old_val & _PAGE_WRITE)) && (new_val & _PAGE_WRITE))
 +              return true;
 +
 +      return false;
 +}
  
  #endif /* __ASSEMBLY__ */
  #endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */
index 77fc21278fa2ad5ba944a7e825bddf8b47caf31b,6c0039f3a3a67101968109baf0b18136104dbff6..fc188e0e91791a80c87d634b2b7a9fc8a4f8b72f
@@@ -10,7 -10,6 +10,7 @@@
  #include <linux/pci.h>
  #include <linux/list.h>
  #include <linux/ioport.h>
 +#include <linux/numa.h>
  
  struct device_node;
  
@@@ -20,6 -19,8 +20,8 @@@
  struct pci_controller_ops {
        void            (*dma_dev_setup)(struct pci_dev *pdev);
        void            (*dma_bus_setup)(struct pci_bus *bus);
+       bool            (*iommu_bypass_supported)(struct pci_dev *pdev,
+                               u64 mask);
  
        int             (*probe_mode)(struct pci_bus *bus);
  
@@@ -44,9 -45,6 +46,6 @@@
        void            (*teardown_msi_irqs)(struct pci_dev *pdev);
  #endif
  
-       int             (*dma_set_mask)(struct pci_dev *pdev, u64 dma_mask);
-       u64             (*dma_get_required_mask)(struct pci_dev *pdev);
        void            (*shutdown)(struct pci_controller *hose);
  };
  
@@@ -266,7 -264,7 +265,7 @@@ extern int pcibios_map_io_space(struct 
  #ifdef CONFIG_NUMA
  #define PHB_SET_NODE(PHB, NODE)               ((PHB)->node = (NODE))
  #else
 -#define PHB_SET_NODE(PHB, NODE)               ((PHB)->node = -1)
 +#define PHB_SET_NODE(PHB, NODE)               ((PHB)->node = NUMA_NO_NODE)
  #endif
  
  #endif        /* CONFIG_PPC64 */
  extern struct pci_controller *pci_find_hose_for_OF_device(
                        struct device_node* node);
  
+ extern struct pci_controller *pci_find_controller_for_domain(int domain_nr);
  /* Fill up host controller resources from the OF node */
  extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
                        struct device_node *dev, int primary);
index f9513ad38fa64f62d0093b9fb9962418c4697e26,2bc9494146697f8662b403f994566a7cb54cdec2..c5698a523bb189dee5650398603c4ac8a0f5bc27
  #define PPC_INST_ADDI                 0x38000000
  #define PPC_INST_ADDIS                        0x3c000000
  #define PPC_INST_ADD                  0x7c000214
+ #define PPC_INST_ADDC                 0x7c000014
  #define PPC_INST_SUB                  0x7c000050
  #define PPC_INST_BLR                  0x4e800020
  #define PPC_INST_BLRL                 0x4e800021
  #define PPC_INST_MULLW                        0x7c0001d6
  #define PPC_INST_MULHWU                       0x7c000016
  #define PPC_INST_MULLI                        0x1c000000
+ #define PPC_INST_MADDHD                       0x10000030
+ #define PPC_INST_MADDHDU              0x10000031
+ #define PPC_INST_MADDLD                       0x10000033
  #define PPC_INST_DIVWU                        0x7c000396
  #define PPC_INST_DIVD                 0x7c0003d2
  #define PPC_INST_RLWINM                       0x54000000
 +#define PPC_INST_RLWINM_DOT           0x54000001
  #define PPC_INST_RLWIMI                       0x50000000
  #define PPC_INST_RLDICL                       0x78000000
  #define PPC_INST_RLDICR                       0x78000004
  /* macros to insert fields into opcodes */
  #define ___PPC_RA(a)  (((a) & 0x1f) << 16)
  #define ___PPC_RB(b)  (((b) & 0x1f) << 11)
+ #define ___PPC_RC(c)  (((c) & 0x1f) << 6)
  #define ___PPC_RS(s)  (((s) & 0x1f) << 21)
  #define ___PPC_RT(t)  ___PPC_RS(t)
  #define ___PPC_R(r)   (((r) & 0x1) << 16)
  #define __PPC_WS(w)   (((w) & 0x1f) << 11)
  #define __PPC_SH(s)   __PPC_WS(s)
  #define __PPC_SH64(s) (__PPC_SH(s) | (((s) & 0x20) >> 4))
- #define __PPC_MB(s)   (((s) & 0x1f) << 6)
+ #define __PPC_MB(s)   ___PPC_RC(s)
  #define __PPC_ME(s)   (((s) & 0x1f) << 1)
  #define __PPC_MB64(s) (__PPC_MB(s) | ((s) & 0x20))
  #define __PPC_ME64(s) __PPC_MB64(s)
  #define PPC_STQCX(t, a, b)    stringify_in_c(.long PPC_INST_STQCX | \
                                        ___PPC_RT(t) | ___PPC_RA(a) | \
                                        ___PPC_RB(b))
+ #define PPC_MADDHD(t, a, b, c)        stringify_in_c(.long PPC_INST_MADDHD | \
+                                       ___PPC_RT(t) | ___PPC_RA(a)  | \
+                                       ___PPC_RB(b) | ___PPC_RC(c))
+ #define PPC_MADDHDU(t, a, b, c)       stringify_in_c(.long PPC_INST_MADDHDU | \
+                                       ___PPC_RT(t) | ___PPC_RA(a)   | \
+                                       ___PPC_RB(b) | ___PPC_RC(c))
+ #define PPC_MADDLD(t, a, b, c)        stringify_in_c(.long PPC_INST_MADDLD | \
+                                       ___PPC_RT(t) | ___PPC_RA(a)  | \
+                                       ___PPC_RB(b) | ___PPC_RC(c))
  #define PPC_MSGSND(b)         stringify_in_c(.long PPC_INST_MSGSND | \
                                        ___PPC_RB(b))
  #define PPC_MSGSYNC           stringify_in_c(.long PPC_INST_MSGSYNC)
index 4538e8ddde807fc11e2392e4263ff13287147b1e,60f20c2e559a4a4efcf3fdde16fbc97501ea3f6c..ff4b7539cbdfdee06ef409780f908c62fa3b2ee4
@@@ -32,7 -32,6 +32,7 @@@
  #include <linux/vmalloc.h>
  #include <linux/slab.h>
  #include <linux/vgaarb.h>
 +#include <linux/numa.h>
  
  #include <asm/processor.h>
  #include <asm/io.h>
@@@ -63,19 -62,13 +63,13 @@@ resource_size_t isa_mem_base
  EXPORT_SYMBOL(isa_mem_base);
  
  
- static const struct dma_map_ops *pci_dma_ops = &dma_nommu_ops;
+ static const struct dma_map_ops *pci_dma_ops;
  
  void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
  {
        pci_dma_ops = dma_ops;
  }
  
- const struct dma_map_ops *get_pci_dma_ops(void)
- {
-       return pci_dma_ops;
- }
- EXPORT_SYMBOL(get_pci_dma_ops);
  /*
   * This function should run under locking protection, specifically
   * hose_spinlock.
@@@ -133,7 -126,7 +127,7 @@@ struct pci_controller *pcibios_alloc_co
                int nid = of_node_to_nid(dev);
  
                if (nid < 0 || !node_online(nid))
 -                      nid = -1;
 +                      nid = NUMA_NO_NODE;
  
                PHB_SET_NODE(phb, nid);
        }
@@@ -358,6 -351,17 +352,17 @@@ struct pci_controller* pci_find_hose_fo
        return NULL;
  }
  
+ struct pci_controller *pci_find_controller_for_domain(int domain_nr)
+ {
+       struct pci_controller *hose;
+       list_for_each_entry(hose, &hose_list, list_node)
+               if (hose->global_number == domain_nr)
+                       return hose;
+       return NULL;
+ }
  /*
   * Reads the interrupt pin to determine if interrupt is use by card.
   * If the interrupt is used, then gets the interrupt line from the
@@@ -973,7 -977,7 +978,7 @@@ static void pcibios_setup_device(struc
  
        /* Hook up default DMA ops */
        set_dma_ops(&dev->dev, pci_dma_ops);
-       set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
+       dev->dev.archdata.dma_offset = PCI_DRAM_OFFSET;
  
        /* Additional platform DMA/iommu setup */
        phb = pci_bus_to_host(dev->bus);
index c31082233a25dcfc70a988acf79d6d68bc8a6173,1f0b7629c1a652694c3ed45dfd3510555a931780..4a65e08a6042f7b63347a54bc35caab26277729d
@@@ -17,7 -17,6 +17,7 @@@
  #include <linux/console.h>
  #include <linux/memblock.h>
  #include <linux/export.h>
 +#include <linux/nvram.h>
  
  #include <asm/io.h>
  #include <asm/prom.h>
@@@ -148,6 -147,41 +148,6 @@@ static int __init ppc_setup_l3cr(char *
  }
  __setup("l3cr=", ppc_setup_l3cr);
  
 -#ifdef CONFIG_GENERIC_NVRAM
 -
 -/* Generic nvram hooks used by drivers/char/gen_nvram.c */
 -unsigned char nvram_read_byte(int addr)
 -{
 -      if (ppc_md.nvram_read_val)
 -              return ppc_md.nvram_read_val(addr);
 -      return 0xff;
 -}
 -EXPORT_SYMBOL(nvram_read_byte);
 -
 -void nvram_write_byte(unsigned char val, int addr)
 -{
 -      if (ppc_md.nvram_write_val)
 -              ppc_md.nvram_write_val(addr, val);
 -}
 -EXPORT_SYMBOL(nvram_write_byte);
 -
 -ssize_t nvram_get_size(void)
 -{
 -      if (ppc_md.nvram_size)
 -              return ppc_md.nvram_size();
 -      return -1;
 -}
 -EXPORT_SYMBOL(nvram_get_size);
 -
 -void nvram_sync(void)
 -{
 -      if (ppc_md.nvram_sync)
 -              ppc_md.nvram_sync();
 -}
 -EXPORT_SYMBOL(nvram_sync);
 -
 -#endif /* CONFIG_NVRAM */
 -
  static int __init ppc_init(void)
  {
        /* clear the progress line */
  }
  arch_initcall(ppc_init);
  
+ static void *__init alloc_stack(void)
+ {
+       void *ptr = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+       if (!ptr)
+               panic("cannot allocate %d bytes for stack at %pS\n",
+                     THREAD_SIZE, (void *)_RET_IP_);
+       return ptr;
+ }
  void __init irqstack_early_init(void)
  {
        unsigned int i;
        /* interrupt stacks must be in lowmem, we get that for free on ppc32
         * as the memblock is limited to lowmem by default */
        for_each_possible_cpu(i) {
-               softirq_ctx[i] = (struct thread_info *)
-                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
-               hardirq_ctx[i] = (struct thread_info *)
-                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
+               softirq_ctx[i] = alloc_stack();
+               hardirq_ctx[i] = alloc_stack();
        }
  }
  
@@@ -190,13 -233,10 +199,10 @@@ void __init exc_lvl_early_init(void
                hw_cpu = 0;
  #endif
  
-               critirq_ctx[hw_cpu] = (struct thread_info *)
-                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
+               critirq_ctx[hw_cpu] = alloc_stack();
  #ifdef CONFIG_BOOKE
-               dbgirq_ctx[hw_cpu] = (struct thread_info *)
-                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
-               mcheckirq_ctx[hw_cpu] = (struct thread_info *)
-                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
+               dbgirq_ctx[hw_cpu] = alloc_stack();
+               mcheckirq_ctx[hw_cpu] = alloc_stack();
  #endif
        }
  }
index 367ce3a4a50395faf636ce72fe78b2a3260b7b84,f6b09edc5e6ec6dc2bb717d12f63783717371d02..b0d9209d9a86fabb963c12c10447e59234499dbe
@@@ -26,7 -26,7 +26,7 @@@ int __hash_page_huge(unsigned long ea, 
        real_pte_t rpte;
        unsigned long vpn;
        unsigned long old_pte, new_pte;
-       unsigned long rflags, pa, sz;
+       unsigned long rflags, pa;
        long slot, offset;
  
        BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
@@@ -73,7 -73,6 +73,6 @@@
                offset = PTRS_PER_PMD;
        rpte = __real_pte(__pte(old_pte), ptep, offset);
  
-       sz = ((1UL) << shift);
        if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
                /* No CPU has hugepages but lacks no execute, so we
                 * don't need to worry about that case */
        *ptep = __pte(new_pte & ~H_PAGE_BUSY);
        return 0;
  }
 +
 +pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
 +                                unsigned long addr, pte_t *ptep)
 +{
 +      unsigned long pte_val;
 +      /*
 +       * Clear the _PAGE_PRESENT so that no hardware parallel update is
 +       * possible. Also keep the pte_present true so that we don't take
 +       * wrong fault.
 +       */
 +      pte_val = pte_update(vma->vm_mm, addr, ptep,
 +                           _PAGE_PRESENT, _PAGE_INVALID, 1);
 +
 +      return __pte(pte_val);
 +}
 +
 +void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,
 +                                pte_t *ptep, pte_t old_pte, pte_t pte)
 +{
 +
 +      if (radix_enabled())
 +              return radix__huge_ptep_modify_prot_commit(vma, addr, ptep,
 +                                                         old_pte, pte);
 +      set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
 +}
index 11d9ea28a816ac2fcf88bf19910ba77298bd004d,97c7a39ebc009c1aa4e9296db096ac0a581a478f..cab06331c0c09478fbba25beac0ebb29cba5d3b1
@@@ -1,6 -1,7 +1,7 @@@
  // SPDX-License-Identifier: GPL-2.0
  #include <linux/mm.h>
  #include <linux/hugetlb.h>
+ #include <linux/security.h>
  #include <asm/pgtable.h>
  #include <asm/pgalloc.h>
  #include <asm/cacheflush.h>
@@@ -73,7 -74,7 +74,7 @@@ radix__hugetlb_get_unmapped_area(struc
        if (addr) {
                addr = ALIGN(addr, huge_page_size(h));
                vma = find_vma(mm, addr);
-               if (high_limit - len >= addr &&
+               if (high_limit - len >= addr && addr >= mmap_min_addr &&
                    (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
         */
        info.flags = VM_UNMAPPED_AREA_TOPDOWN;
        info.length = len;
-       info.low_limit = PAGE_SIZE;
+       info.low_limit = max(PAGE_SIZE, mmap_min_addr);
        info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW);
        info.align_mask = PAGE_MASK & ~huge_page_mask(h);
        info.align_offset = 0;
  
        return vm_unmapped_area(&info);
  }
 +
 +void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
 +                                       unsigned long addr, pte_t *ptep,
 +                                       pte_t old_pte, pte_t pte)
 +{
 +      struct mm_struct *mm = vma->vm_mm;
 +
 +      /*
 +       * To avoid NMMU hang while relaxing access we need to flush the tlb before
 +       * we set the new value.
 +       */
 +      if (is_pte_rw_upgrade(pte_val(old_pte), pte_val(pte)) &&
 +          (atomic_read(&mm->context.copros) > 0))
 +              radix__flush_hugetlb_page(vma, addr);
 +
 +      set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
 +}
diff --combined arch/powerpc/mm/numa.c
index df1e11ebbabbfb9647a7f81bfd41d98259212f03,b5d1c45c14758001e9b61849d31eeb36c82c264c..ac49e4158e50880ee5bdc86af956f728b533f250
@@@ -84,7 -84,7 +84,7 @@@ static void __init setup_node_to_cpumas
                alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
  
        /* cpumask_of_node() will now work */
 -      dbg("Node to cpumask map for %d nodes\n", nr_node_ids);
 +      dbg("Node to cpumask map for %u nodes\n", nr_node_ids);
  }
  
  static int __init fake_numa_create_new_node(unsigned long end_pfn,
@@@ -215,7 -215,7 +215,7 @@@ static void initialize_distance_lookup_
   */
  static int associativity_to_nid(const __be32 *associativity)
  {
 -      int nid = -1;
 +      int nid = NUMA_NO_NODE;
  
        if (min_common_depth == -1)
                goto out;
  
        /* POWER4 LPAR uses 0xffff as invalid node */
        if (nid == 0xffff || nid >= MAX_NUMNODES)
 -              nid = -1;
 +              nid = NUMA_NO_NODE;
  
        if (nid > 0 &&
                of_read_number(associativity, 1) >= distance_ref_points_depth) {
@@@ -244,7 -244,7 +244,7 @@@ out
   */
  static int of_node_to_nid_single(struct device_node *device)
  {
 -      int nid = -1;
 +      int nid = NUMA_NO_NODE;
        const __be32 *tmp;
  
        tmp = of_get_associativity(device);
  /* Walk the device tree upwards, looking for an associativity id */
  int of_node_to_nid(struct device_node *device)
  {
 -      int nid = -1;
 +      int nid = NUMA_NO_NODE;
  
        of_node_get(device);
        while (device) {
@@@ -454,7 -454,7 +454,7 @@@ static int of_drconf_to_nid_single(stru
   */
  static int numa_setup_cpu(unsigned long lcpu)
  {
 -      int nid = -1;
 +      int nid = NUMA_NO_NODE;
        struct device_node *cpu;
  
        /*
@@@ -930,7 -930,7 +930,7 @@@ static int hot_add_drconf_scn_to_nid(un
  {
        struct drmem_lmb *lmb;
        unsigned long lmb_size;
 -      int nid = -1;
 +      int nid = NUMA_NO_NODE;
  
        lmb_size = drmem_lmb_size();
  
  static int hot_add_node_scn_to_nid(unsigned long scn_addr)
  {
        struct device_node *memory;
 -      int nid = -1;
 +      int nid = NUMA_NO_NODE;
  
        for_each_node_by_type(memory, "memory") {
                unsigned long start, size;
@@@ -1460,13 -1460,6 +1460,6 @@@ static void reset_topology_timer(void
  
  #ifdef CONFIG_SMP
  
- static void stage_topology_update(int core_id)
- {
-       cpumask_or(&cpu_associativity_changes_mask,
-               &cpu_associativity_changes_mask, cpu_sibling_mask(core_id));
-       reset_topology_timer();
- }
  static int dt_update_callback(struct notifier_block *nb,
                                unsigned long action, void *data)
  {
                    !of_prop_cmp(update->prop->name, "ibm,associativity")) {
                        u32 core_id;
                        of_property_read_u32(update->dn, "reg", &core_id);
-                       stage_topology_update(core_id);
+                       rc = dlpar_cpu_readd(core_id);
                        rc = NOTIFY_OK;
                }
                break;
index 145373f0e5dc082ecd34f062143b88c82c22b24c,f1ce39f64329834c1c6f6e1908651f0129bde66b..fa6af52b5219f309a3451589a341fecb3c83edf5
@@@ -1593,8 -1593,6 +1593,8 @@@ static void pnv_ioda_setup_vf_PE(struc
  
                pnv_pci_ioda2_setup_dma_pe(phb, pe);
  #ifdef CONFIG_IOMMU_API
 +              iommu_register_group(&pe->table_group,
 +                              pe->phb->hose->global_number, pe->pe_number);
                pnv_ioda_setup_bus_iommu_group(pe, &pe->table_group, NULL);
  #endif
        }
@@@ -1748,7 -1746,7 +1748,7 @@@ static void pnv_pci_ioda_dma_dev_setup(
  
        pe = &phb->ioda.pe_array[pdn->pe_number];
        WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops);
-       set_dma_offset(&pdev->dev, pe->tce_bypass_base);
+       pdev->dev.archdata.dma_offset = pe->tce_bypass_base;
        set_iommu_table_base(&pdev->dev, pe->table_group.tables[0]);
        /*
         * Note: iommu_add_device() will fail here as
         */
  }
  
- static bool pnv_pci_ioda_pe_single_vendor(struct pnv_ioda_pe *pe)
- {
-       unsigned short vendor = 0;
-       struct pci_dev *pdev;
-       if (pe->device_count == 1)
-               return true;
-       /* pe->pdev should be set if it's a single device, pe->pbus if not */
-       if (!pe->pbus)
-               return true;
-       list_for_each_entry(pdev, &pe->pbus->devices, bus_list) {
-               if (!vendor) {
-                       vendor = pdev->vendor;
-                       continue;
-               }
-               if (pdev->vendor != vendor)
-                       return false;
-       }
-       return true;
- }
  /*
   * Reconfigure TVE#0 to be usable as 64-bit DMA space.
   *
        return -EIO;
  }
  
- static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
+ static bool pnv_pci_ioda_iommu_bypass_supported(struct pci_dev *pdev,
+               u64 dma_mask)
  {
        struct pci_controller *hose = pci_bus_to_host(pdev->bus);
        struct pnv_phb *phb = hose->private_data;
        struct pci_dn *pdn = pci_get_pdn(pdev);
        struct pnv_ioda_pe *pe;
-       uint64_t top;
-       bool bypass = false;
-       s64 rc;
  
        if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
                return -ENODEV;
  
        pe = &phb->ioda.pe_array[pdn->pe_number];
        if (pe->tce_bypass_enabled) {
-               top = pe->tce_bypass_base + memblock_end_of_DRAM() - 1;
-               bypass = (dma_mask >= top);
+               u64 top = pe->tce_bypass_base + memblock_end_of_DRAM() - 1;
+               if (dma_mask >= top)
+                       return true;
        }
  
-       if (bypass) {
-               dev_info(&pdev->dev, "Using 64-bit DMA iommu bypass\n");
-               set_dma_ops(&pdev->dev, &dma_nommu_ops);
-       } else {
-               /*
-                * If the device can't set the TCE bypass bit but still wants
-                * to access 4GB or more, on PHB3 we can reconfigure TVE#0 to
-                * bypass the 32-bit region and be usable for 64-bit DMAs.
-                * The device needs to be able to address all of this space.
-                */
-               if (dma_mask >> 32 &&
-                   dma_mask > (memory_hotplug_max() + (1ULL << 32)) &&
-                   pnv_pci_ioda_pe_single_vendor(pe) &&
-                   phb->model == PNV_PHB_MODEL_PHB3) {
-                       /* Configure the bypass mode */
-                       rc = pnv_pci_ioda_dma_64bit_bypass(pe);
-                       if (rc)
-                               return rc;
-                       /* 4GB offset bypasses 32-bit space */
-                       set_dma_offset(&pdev->dev, (1ULL << 32));
-                       set_dma_ops(&pdev->dev, &dma_nommu_ops);
-               } else if (dma_mask >> 32 && dma_mask != DMA_BIT_MASK(64)) {
-                       /*
-                        * Fail the request if a DMA mask between 32 and 64 bits
-                        * was requested but couldn't be fulfilled. Ideally we
-                        * would do this for 64-bits but historically we have
-                        * always fallen back to 32-bits.
-                        */
-                       return -ENOMEM;
-               } else {
-                       dev_info(&pdev->dev, "Using 32-bit DMA via iommu\n");
-                       set_dma_ops(&pdev->dev, &dma_iommu_ops);
-               }
+       /*
+        * If the device can't set the TCE bypass bit but still wants
+        * to access 4GB or more, on PHB3 we can reconfigure TVE#0 to
+        * bypass the 32-bit region and be usable for 64-bit DMAs.
+        * The device needs to be able to address all of this space.
+        */
+       if (dma_mask >> 32 &&
+           dma_mask > (memory_hotplug_max() + (1ULL << 32)) &&
+           /* pe->pdev should be set if it's a single device, pe->pbus if not */
+           (pe->device_count == 1 || !pe->pbus) &&
+           phb->model == PNV_PHB_MODEL_PHB3) {
+               /* Configure the bypass mode */
+               s64 rc = pnv_pci_ioda_dma_64bit_bypass(pe);
+               if (rc)
+                       return rc;
+               /* 4GB offset bypasses 32-bit space */
+               pdev->dev.archdata.dma_offset = (1ULL << 32);
+               return true;
        }
-       *pdev->dev.dma_mask = dma_mask;
  
-       /* Update peer npu devices */
-       pnv_npu_try_dma_set_bypass(pdev, bypass);
-       return 0;
- }
- static u64 pnv_pci_ioda_dma_get_required_mask(struct pci_dev *pdev)
- {
-       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
-       struct pnv_phb *phb = hose->private_data;
-       struct pci_dn *pdn = pci_get_pdn(pdev);
-       struct pnv_ioda_pe *pe;
-       u64 end, mask;
-       if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
-               return 0;
-       pe = &phb->ioda.pe_array[pdn->pe_number];
-       if (!pe->tce_bypass_enabled)
-               return __dma_get_required_mask(&pdev->dev);
-       end = pe->tce_bypass_base + memblock_end_of_DRAM();
-       mask = 1ULL << (fls64(end) - 1);
-       mask += mask - 1;
-       return mask;
+       return false;
  }
  
  static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
  
        list_for_each_entry(dev, &bus->devices, bus_list) {
                set_iommu_table_base(&dev->dev, pe->table_group.tables[0]);
-               set_dma_offset(&dev->dev, pe->tce_bypass_base);
+               dev->dev.archdata.dma_offset = pe->tce_bypass_base;
  
                if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate)
                        pnv_ioda_setup_bus_dma(pe, dev->subordinate);
@@@ -2594,8 -2524,13 +2526,13 @@@ static long pnv_pci_ioda2_create_table_
                int num, __u32 page_shift, __u64 window_size, __u32 levels,
                struct iommu_table **ptbl)
  {
-       return pnv_pci_ioda2_create_table(table_group,
+       long ret = pnv_pci_ioda2_create_table(table_group,
                        num, page_shift, window_size, levels, true, ptbl);
+       if (!ret)
+               (*ptbl)->it_allocated_size = pnv_pci_ioda2_get_table_size(
+                               page_shift, window_size, levels);
+       return ret;
  }
  
  static void pnv_ioda2_take_ownership(struct iommu_table_group *table_group)
@@@ -3661,6 -3596,7 +3598,7 @@@ static void pnv_pci_ioda_shutdown(struc
  static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
        .dma_dev_setup          = pnv_pci_dma_dev_setup,
        .dma_bus_setup          = pnv_pci_dma_bus_setup,
+       .iommu_bypass_supported = pnv_pci_ioda_iommu_bypass_supported,
        .setup_msi_irqs         = pnv_setup_msi_irqs,
        .teardown_msi_irqs      = pnv_teardown_msi_irqs,
        .enable_device_hook     = pnv_pci_enable_device_hook,
        .window_alignment       = pnv_pci_window_alignment,
        .setup_bridge           = pnv_pci_setup_bridge,
        .reset_secondary_bus    = pnv_pci_reset_secondary_bus,
-       .dma_set_mask           = pnv_pci_ioda_dma_set_mask,
-       .dma_get_required_mask  = pnv_pci_ioda_dma_get_required_mask,
        .shutdown               = pnv_pci_ioda_shutdown,
  };
  
- static int pnv_npu_dma_set_mask(struct pci_dev *npdev, u64 dma_mask)
- {
-       dev_err_once(&npdev->dev,
-                       "%s operation unsupported for NVLink devices\n",
-                       __func__);
-       return -EPERM;
- }
  static const struct pci_controller_ops pnv_npu_ioda_controller_ops = {
        .dma_dev_setup          = pnv_pci_dma_dev_setup,
        .setup_msi_irqs         = pnv_setup_msi_irqs,
        .enable_device_hook     = pnv_pci_enable_device_hook,
        .window_alignment       = pnv_pci_window_alignment,
        .reset_secondary_bus    = pnv_pci_reset_secondary_bus,
-       .dma_set_mask           = pnv_npu_dma_set_mask,
        .shutdown               = pnv_pci_ioda_shutdown,
        .disable_device         = pnv_npu_disable_device,
  };
@@@ -3946,9 -3871,12 +3873,12 @@@ static void __init pnv_pci_init_ioda_ph
         * shutdown PCI devices correctly. We already got IODA table
         * cleaned out. So we have to issue PHB reset to stop all PCI
         * transactions from previous kernel. The ppc_pci_reset_phbs
-        * kernel parameter will force this reset too.
+        * kernel parameter will force this reset too. Additionally,
+        * if the IODA reset above failed then use a bigger hammer.
+        * This can happen if we get a PHB fatal error in very early
+        * boot.
         */
-       if (is_kdump_kernel() || pci_reset_phbs) {
+       if (is_kdump_kernel() || pci_reset_phbs || rc) {
                pr_info("  Issue PHB reset ...\n");
                pnv_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL);
                pnv_eeh_phb_reset(hose, EEH_RESET_DEACTIVATE);
diff --combined kernel/dma/swiotlb.c
index 1fb6fd68b9c7e80c969072642a4064f4e9608008,cbf3498a46f95abdefefdbffe5c143a151336867..6d0236bd3929c4e6f7092d902c92e9fc893526a0
@@@ -378,8 -378,6 +378,8 @@@ void __init swiotlb_exit(void
                memblock_free_late(io_tlb_start,
                                   PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
        }
 +      io_tlb_start = 0;
 +      io_tlb_end = 0;
        io_tlb_nslabs = 0;
        max_segment = 0;
  }
@@@ -650,15 -648,3 +650,3 @@@ bool swiotlb_map(struct device *dev, ph
  
        return true;
  }
- /*
-  * Return whether the given device DMA address mask can be supported
-  * properly.  For example, if your device can only drive the low 24-bits
-  * during bus mastering, then you would pass 0x00ffffff as the mask to
-  * this function.
-  */
- int
- swiotlb_dma_supported(struct device *hwdev, u64 mask)
- {
-       return __phys_to_dma(hwdev, io_tlb_end - 1) <= mask;
- }
This page took 0.123077 seconds and 4 git commands to generate.