1. 02 4月, 2015 1 次提交
    • G
      ARM: 8338/1: kexec: Relax SMP validation to improve DT compatibility · fee3fd4f
      Geert Uytterhoeven 提交于
      When trying to kexec into a new kernel on a platform where multiple CPU
      cores are present, but no SMP bringup code is available yet, the
      kexec_load system call fails with:
      
          kexec_load failed: Invalid argument
      
      The SMP test added to machine_kexec_prepare() in commit 2103f6cb
      ("ARM: 7807/1: kexec: validate CPU hotplug support") wants to prohibit
      kexec on SMP platforms where it cannot disable secondary CPUs.
      However, this test is too strict: if the secondary CPUs couldn't be
      enabled in the first place, there's no need to disable them later at
      kexec time.  Hence skip the test in the absence of SMP bringup code.
      
      This allows to add all CPU cores to the DTS from the beginning, without
      having to implement SMP bringup first, improving DT compatibility.
      Signed-off-by: NGeert Uytterhoeven <geert+renesas@glider.be>
      Acked-by: NStephen Warren <swarren@nvidia.com>
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      fee3fd4f
  2. 27 8月, 2014 1 次提交
  3. 14 8月, 2013 1 次提交
  4. 24 6月, 2013 1 次提交
  5. 20 6月, 2013 2 次提交
    • L
      ARM: kernel: implement stack pointer save array through MPIDR hashing · 7604537b
      Lorenzo Pieralisi 提交于
      Current implementation of cpu_{suspend}/cpu_{resume} relies on the MPIDR
      to index the array of pointers where the context is saved and restored.
      The current approach works as long as the MPIDR can be considered a
      linear index, so that the pointers array can simply be dereferenced by
      using the MPIDR[7:0] value.
      On ARM multi-cluster systems, where the MPIDR may not be a linear index,
      to properly dereference the stack pointer array, a mapping function should
      be applied to it so that it can be used for arrays look-ups.
      
      This patch adds code in the cpu_{suspend}/cpu_{resume} implementation
      that relies on shifting and ORing hashing method to map a MPIDR value to a
      set of buckets precomputed at boot to have a collision free mapping from
      MPIDR to context pointers.
      
      The hashing algorithm must be simple, fast, and implementable with few
      instructions since in the cpu_resume path the mapping is carried out with
      the MMU off and the I-cache off, hence code and data are fetched from DRAM
      with no-caching available. Simplicity is counterbalanced with a little
      increase of memory (allocated dynamically) for stack pointers buckets, that
      should be anyway fairly limited on most systems.
      
      Memory for context pointers is allocated in a early_initcall with
      size precomputed and stashed previously in kernel data structures.
      Memory for context pointers is allocated through kmalloc; this
      guarantees contiguous physical addresses for the allocated memory which
      is fundamental to the correct functioning of the resume mechanism that
      relies on the context pointer array to be a chunk of contiguous physical
      memory. Virtual to physical address conversion for the context pointer
      array base is carried out at boot to avoid fiddling with virt_to_phys
      conversions in the cpu_resume path which is quite fragile and should be
      optimized to execute as few instructions as possible.
      Virtual and physical context pointer base array addresses are stashed in a
      struct that is accessible from assembly using values generated through the
      asm-offsets.c mechanism.
      
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Russell King <linux@arm.linux.org.uk>
      Cc: Colin Cross <ccross@android.com>
      Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
      Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
      Cc: Amit Kucheria <amit.kucheria@linaro.org>
      Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Reviewed-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NNicolas Pitre <nico@linaro.org>
      Tested-by: NShawn Guo <shawn.guo@linaro.org>
      Tested-by: NKevin Hilman <khilman@linaro.org>
      Tested-by: NStephen Warren <swarren@wwwdotorg.org>
      7604537b
    • L
      ARM: kernel: build MPIDR hash function data structure · 8cf72172
      Lorenzo Pieralisi 提交于
      On ARM SMP systems, cores are identified by their MPIDR register.
      The MPIDR guidelines in the ARM ARM do not provide strict enforcement of
      MPIDR layout, only recommendations that, if followed, split the MPIDR
      on ARM 32 bit platforms in three affinity levels. In multi-cluster
      systems like big.LITTLE, if the affinity guidelines are followed, the
      MPIDR can not be considered an index anymore. This means that the
      association between logical CPU in the kernel and the HW CPU identifier
      becomes somewhat more complicated requiring methods like hashing to
      associate a given MPIDR to a CPU logical index, in order for the look-up
      to be carried out in an efficient and scalable way.
      
      This patch provides a function in the kernel that starting from the
      cpu_logical_map, implement collision-free hashing of MPIDR values by checking
      all significative bits of MPIDR affinity level bitfields. The hashing
      can then be carried out through bits shifting and ORing; the resulting
      hash algorithm is a collision-free though not minimal hash that can be
      executed with few assembly instructions. The mpidr is filtered through a
      mpidr mask that is built by checking all bits that toggle in the set of
      MPIDRs corresponding to possible CPUs. Bits that do not toggle do not carry
      information so they do not contribute to the resulting hash.
      
      Pseudo code:
      
      /* check all bits that toggle, so they are required */
      for (i = 1, mpidr_mask = 0; i < num_possible_cpus(); i++)
      	mpidr_mask |= (cpu_logical_map(i) ^ cpu_logical_map(0));
      
      /*
       * Build shifts to be applied to aff0, aff1, aff2 values to hash the mpidr
       * fls() returns the last bit set in a word, 0 if none
       * ffs() returns the first bit set in a word, 0 if none
       */
      fs0 = mpidr_mask[7:0] ? ffs(mpidr_mask[7:0]) - 1 : 0;
      fs1 = mpidr_mask[15:8] ? ffs(mpidr_mask[15:8]) - 1 : 0;
      fs2 = mpidr_mask[23:16] ? ffs(mpidr_mask[23:16]) - 1 : 0;
      ls0 = fls(mpidr_mask[7:0]);
      ls1 = fls(mpidr_mask[15:8]);
      ls2 = fls(mpidr_mask[23:16]);
      bits0 = ls0 - fs0;
      bits1 = ls1 - fs1;
      bits2 = ls2 - fs2;
      aff0_shift = fs0;
      aff1_shift = 8 + fs1 - bits0;
      aff2_shift = 16 + fs2 - (bits0 + bits1);
      u32 hash(u32 mpidr) {
      	u32 l0, l1, l2;
      	u32 mpidr_masked = mpidr & mpidr_mask;
      	l0 = mpidr_masked & 0xff;
      	l1 = mpidr_masked & 0xff00;
      	l2 = mpidr_masked & 0xff0000;
      	return (l0 >> aff0_shift | l1 >> aff1_shift | l2 >> aff2_shift);
      }
      
      The hashing algorithm relies on the inherent properties set in the ARM ARM
      recommendations for the MPIDR. Exotic configurations, where for instance the
      MPIDR values at a given affinity level have large holes, can end up requiring
      big hash tables since the compression of values that can be achieved through
      shifting is somewhat crippled when holes are present. Kernel warns if
      the number of buckets of the resulting hash table exceeds the number of
      possible CPUs by a factor of 4, which is a symptom of a very sparse HW
      MPIDR configuration.
      
      The hash algorithm is quite simple and can easily be implemented in assembly
      code, to be used in code paths where the kernel virtual address space is
      not set-up (ie cpu_resume) and instruction and data fetches are strongly
      ordered so code must be compact and must carry out few data accesses.
      
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Russell King <linux@arm.linux.org.uk>
      Cc: Colin Cross <ccross@android.com>
      Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
      Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
      Cc: Amit Kucheria <amit.kucheria@linaro.org>
      Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Reviewed-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NNicolas Pitre <nico@linaro.org>
      Tested-by: NShawn Guo <shawn.guo@linaro.org>
      Tested-by: NKevin Hilman <khilman@linaro.org>
      Tested-by: NStephen Warren <swarren@wwwdotorg.org>
      8cf72172
  6. 08 6月, 2013 1 次提交
    • W
      ARM: nommu: define dummy TLB operations for nommu configurations · 5c709e69
      Will Deacon 提交于
      nommu platforms do not perform address translation and therefore clearly
      don't have TLBs. However, some SMP code assumes the presence of the TLB
      flushing routines and will therefore fail to compile for a nommu system.
      
      This patch defines dummy local_* TLB operations and #defines
      tlb_ops_need_broadcast() as 0, therefore causing the usual ARM SMP TLB
      operations to call the local variants instead.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      CC: Nicolas Pitre <nico@linaro.org>
      5c709e69
  7. 19 11月, 2012 1 次提交
  8. 23 1月, 2012 1 次提交
  9. 08 10月, 2010 1 次提交
  10. 05 10月, 2010 1 次提交
    • R
      ARM: Allow SMP kernels to boot on UP systems · f00ec48f
      Russell King 提交于
      UP systems do not implement all the instructions that SMP systems have,
      so in order to boot a SMP kernel on a UP system, we need to rewrite
      parts of the kernel.
      
      Do this using an 'alternatives' scheme, where the kernel code and data
      is modified prior to initialization to replace the SMP instructions,
      thereby rendering the problematical code ineffectual.  We use the linker
      to generate a list of 32-bit word locations and their replacement values,
      and run through these replacements when we detect a UP system.
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      f00ec48f
  11. 19 9月, 2010 1 次提交
  12. 14 12月, 2009 1 次提交
  13. 29 9月, 2009 1 次提交
    • R
      ARM: Don't allow highmem on SMP platforms without h/w TLB ops broadcast · e616c591
      Russell King 提交于
      We suffer an unfortunate combination of "features" which makes highmem
      support on platforms without hardware TLB maintainence broadcast difficult:
      
      - we need kmap_high_get() support for DMA cache coherence
      - this requires kmap_high() to take a spinlock with IRQs disabled
      - kmap_high() occasionally calls flush_all_zero_pkmaps() to clear
        out old mappings
      - flush_all_zero_pkmaps() calls flush_tlb_kernel_range(), which
        on s/w IPI'd systems eventually calls smp_call_function_many()
      - smp_call_function_many() must not be called with IRQs disabled:
      
      WARNING: at kernel/smp.c:380 smp_call_function_many+0xc4/0x240()
      Modules linked in:
      Backtrace:
      [<c00306f0>] (dump_backtrace+0x0/0x108) from [<c0286e6c>] (dump_stack+0x18/0x1c)
       r6:c007cd18 r5:c02ff228 r4:0000017c
      [<c0286e54>] (dump_stack+0x0/0x1c) from [<c0053e08>] (warn_slowpath_common+0x50/0x80)
      [<c0053db8>] (warn_slowpath_common+0x0/0x80) from [<c0053e50>] (warn_slowpath_null+0x18/0x1c)
       r7:00000003 r6:00000001 r5:c1ff4000 r4:c035fa34
      [<c0053e38>] (warn_slowpath_null+0x0/0x1c) from [<c007cd18>] (smp_call_function_many+0xc4/0x240)
      [<c007cc54>] (smp_call_function_many+0x0/0x240) from [<c007cec0>] (smp_call_function+0x2c/0x38)
      [<c007ce94>] (smp_call_function+0x0/0x38) from [<c005980c>] (on_each_cpu+0x1c/0x38)
      [<c00597f0>] (on_each_cpu+0x0/0x38) from [<c0031788>] (flush_tlb_kernel_range+0x50/0x58)
       r6:00000001 r5:00000800 r4:c05f3590
      [<c0031738>] (flush_tlb_kernel_range+0x0/0x58) from [<c009c600>] (flush_all_zero_pkmaps+0xc0/0xe8)
      [<c009c540>] (flush_all_zero_pkmaps+0x0/0xe8) from [<c009c6b4>] (kmap_high+0x8c/0x1e0)
      [<c009c628>] (kmap_high+0x0/0x1e0) from [<c00364a8>] (kmap+0x44/0x5c)
      [<c0036464>] (kmap+0x0/0x5c) from [<c0109dfc>] (cramfs_readpage+0x3c/0x194)
      [<c0109dc0>] (cramfs_readpage+0x0/0x194) from [<c0090c14>] (__do_page_cache_readahead+0x1f0/0x290)
      [<c0090a24>] (__do_page_cache_readahead+0x0/0x290) from [<c0090ce4>] (ra_submit+0x30/0x38)
      [<c0090cb4>] (ra_submit+0x0/0x38) from [<c0089384>] (filemap_fault+0x3dc/0x438)
       r4:c1819988
      [<c0088fa8>] (filemap_fault+0x0/0x438) from [<c009d21c>] (__do_fault+0x58/0x43c)
      [<c009d1c4>] (__do_fault+0x0/0x43c) from [<c009e8cc>] (handle_mm_fault+0x104/0x318)
      [<c009e7c8>] (handle_mm_fault+0x0/0x318) from [<c0033c98>] (do_page_fault+0x188/0x1e4)
      [<c0033b10>] (do_page_fault+0x0/0x1e4) from [<c0033ddc>] (do_translation_fault+0x7c/0x84)
      [<c0033d60>] (do_translation_fault+0x0/0x84) from [<c002b474>] (do_DataAbort+0x40/0xa4)
       r8:c1ff5e20 r7:c0340120 r6:00000805 r5:c1ff5e54 r4:c03400d0
      [<c002b434>] (do_DataAbort+0x0/0xa4) from [<c002bcac>] (__dabt_svc+0x4c/0x60)
      ...
      
      So we disable highmem support on these systems.
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      e616c591