1. 01 2月, 2017 1 次提交
    • C
      arm64: Work around Falkor erratum 1009 · d9ff80f8
      Christopher Covington 提交于
      During a TLB invalidate sequence targeting the inner shareable domain,
      Falkor may prematurely complete the DSB before all loads and stores using
      the old translation are observed. Instruction fetches are not subject to
      the conditions of this erratum. If the original code sequence includes
      multiple TLB invalidate instructions followed by a single DSB, onle one of
      the TLB instructions needs to be repeated to work around this erratum.
      While the erratum only applies to cases in which the TLBI specifies the
      inner-shareable domain (*IS form of TLBI) and the DSB is ISH form or
      stronger (OSH, SYS), this changes applies the workaround overabundantly--
      to local TLBI, DSB NSH sequences as well--for simplicity.
      
      Based on work by Shanker Donthineni <shankerd@codeaurora.org>
      Signed-off-by: NChristopher Covington <cov@codeaurora.org>
      Acked-by: NMark Rutland <mark.rutland@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      d9ff80f8
  2. 28 9月, 2016 1 次提交
  3. 07 10月, 2015 3 次提交
  4. 28 7月, 2015 2 次提交
    • C
      arm64: Use last level TLBI for user pte changes · 4150e50b
      Catalin Marinas 提交于
      The flush_tlb_page() function is used on user address ranges when PTEs
      (or PMDs/PUDs for huge pages) were changed (attributes or clearing). For
      such cases, it is more efficient to invalidate only the last level of
      the TLB with the "tlbi vale1is" instruction.
      
      In the TLB shoot-down case, the TLB caching of the intermediate page
      table levels (pmd, pud, pgd) is handled by __flush_tlb_pgtable() via the
      __(pte|pmd|pud)_free_tlb() functions and it is not deferred to
      tlb_finish_mmu() (as of commit 285994a6 - "arm64: Invalidate the TLB
      corresponding to intermediate page table levels"). The tlb_flush()
      function only needs to invalidate the TLB for the last level of page
      tables; the __flush_tlb_range() function gains a fourth argument for
      last level TLBI.
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      4150e50b
    • C
      arm64: Clean up __flush_tlb(_kernel)_range functions · da4e7330
      Catalin Marinas 提交于
      This patch moves the MAX_TLB_RANGE check into the
      flush_tlb(_kernel)_range functions directly to avoid the
      undescore-prefixed definitions (and for consistency with a subsequent
      patch).
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      da4e7330
  5. 27 7月, 2015 1 次提交
    • W
      arm64: move update_mmu_cache() into asm/pgtable.h · cba3574f
      Will Deacon 提交于
      Mark Brown reported an allnoconfig build failure in -next:
      
        Today's linux-next fails to build an arm64 allnoconfig due to "mm:
        make GUP handle pfn mapping unless FOLL_GET is requested" which
        causes:
      
        >       arm64-allnoconfig
        > ../mm/gup.c:51:4: error: implicit declaration of function
          'update_mmu_cache' [-Werror=implicit-function-declaration]
      
      Fix the error by moving the function to asm/pgtable.h, as is the case
      for most other architectures.
      Reported-by: NMark Brown <broonie@kernel.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      cba3574f
  6. 12 6月, 2015 1 次提交
  7. 14 3月, 2015 1 次提交
    • C
      arm64: Invalidate the TLB corresponding to intermediate page table levels · 285994a6
      Catalin Marinas 提交于
      The ARM architecture allows the caching of intermediate page table
      levels and page table freeing requires a sequence like:
      
      	pmd_clear()
      	TLB invalidation
      	pte page freeing
      
      With commit 5e5f6dc1 (arm64: mm: enable HAVE_RCU_TABLE_FREE logic),
      the page table freeing batching was moved from tlb_remove_page() to
      tlb_remove_table(). The former takes care of TLB invalidation as this is
      also shared with pte clearing and page cache page freeing. The latter,
      however, does not invalidate the TLBs for intermediate page table levels
      as it probably relies on the architecture code to do it if required.
      When the mm->mm_users < 2, tlb_remove_table() does not do any batching
      and page table pages are freed before tlb_finish_mmu() which performs
      the actual TLB invalidation.
      
      This patch introduces __tlb_flush_pgtable() for arm64 and calls it from
      the {pte,pmd,pud}_free_tlb() directly without relying on deferred page
      table freeing.
      
      Fixes: 5e5f6dc1 arm64: mm: enable HAVE_RCU_TABLE_FREE logic
      Reported-by: NJon Masters <jcm@redhat.com>
      Tested-by: NJon Masters <jcm@redhat.com>
      Tested-by: NSteve Capper <steve.capper@linaro.org>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      285994a6
  8. 27 2月, 2015 1 次提交
  9. 25 7月, 2014 1 次提交
    • M
      arm64: fix soft lockup due to large tlb flush range · 05ac6530
      Mark Salter 提交于
      Under certain loads, this soft lockup has been observed:
      
         BUG: soft lockup - CPU#2 stuck for 22s! [ip6tables:1016]
         Modules linked in: ip6t_rpfilter ip6t_REJECT cfg80211 rfkill xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw vfat fat efivarfs xfs libcrc32c
      
         CPU: 2 PID: 1016 Comm: ip6tables Not tainted 3.13.0-0.rc7.30.sa2.aarch64 #1
         task: fffffe03e81d1400 ti: fffffe03f01f8000 task.ti: fffffe03f01f8000
         PC is at __cpu_flush_kern_tlb_range+0xc/0x40
         LR is at __purge_vmap_area_lazy+0x28c/0x3ac
         pc : [<fffffe000009c5cc>] lr : [<fffffe0000182710>] pstate: 80000145
         sp : fffffe03f01fbb70
         x29: fffffe03f01fbb70 x28: fffffe03f01f8000
         x27: fffffe0000b19000 x26: 00000000000000d0
         x25: 000000000000001c x24: fffffe03f01fbc50
         x23: fffffe03f01fbc58 x22: fffffe03f01fbc10
         x21: fffffe0000b2a3f8 x20: 0000000000000802
         x19: fffffe0000b2a3c8 x18: 000003fffdf52710
         x17: 000003ff9d8bb910 x16: fffffe000050fbfc
         x15: 0000000000005735 x14: 000003ff9d7e1a5c
         x13: 0000000000000000 x12: 000003ff9d7e1a5c
         x11: 0000000000000007 x10: fffffe0000c09af0
         x9 : fffffe0000ad1000 x8 : 000000000000005c
         x7 : fffffe03e8624000 x6 : 0000000000000000
         x5 : 0000000000000000 x4 : 0000000000000000
         x3 : fffffe0000c09cc8 x2 : 0000000000000000
         x1 : 000fffffdfffca80 x0 : 000fffffcd742150
      
      The __cpu_flush_kern_tlb_range() function looks like:
      
        ENTRY(__cpu_flush_kern_tlb_range)
      	dsb	sy
      	lsr	x0, x0, #12
      	lsr	x1, x1, #12
        1:	tlbi	vaae1is, x0
      	add	x0, x0, #1
      	cmp	x0, x1
      	b.lo	1b
      	dsb	sy
      	isb
      	ret
        ENDPROC(__cpu_flush_kern_tlb_range)
      
      The above soft lockup shows the PC at tlbi insn with:
      
        x0 = 0x000fffffcd742150
        x1 = 0x000fffffdfffca80
      
      So __cpu_flush_kern_tlb_range has 0x128ba930 tlbi flushes left
      after it has already been looping for 23 seconds!.
      
      Looking up one frame at __purge_vmap_area_lazy(), there is:
      
      	...
      	list_for_each_entry_rcu(va, &vmap_area_list, list) {
      		if (va->flags & VM_LAZY_FREE) {
      			if (va->va_start < *start)
      				*start = va->va_start;
      			if (va->va_end > *end)
      				*end = va->va_end;
      			nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
      			list_add_tail(&va->purge_list, &valist);
      			va->flags |= VM_LAZY_FREEING;
      			va->flags &= ~VM_LAZY_FREE;
      		}
      	}
      	...
      	if (nr || force_flush)
      		flush_tlb_kernel_range(*start, *end);
      
      So if two areas are being freed, the range passed to
      flush_tlb_kernel_range() may be as large as the vmalloc
      space. For arm64, this is ~240GB for 4k pagesize and ~2TB
      for 64kpage size.
      
      This patch works around this problem by adding a loop limit.
      If the range is larger than the limit, use flush_tlb_all()
      rather than flushing based on individual pages. The limit
      chosen is arbitrary as the TLB size is implementation
      specific and not accessible in an architected way. The aim
      of the arbitrary limit is to avoid soft lockup.
      Signed-off-by: NMark Salter <msalter@redhat.com>
      [catalin.marinas@arm.com: commit log update]
      [catalin.marinas@arm.com: marginal optimisation]
      [catalin.marinas@arm.com: changed to MAX_TLB_RANGE and added comment]
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      05ac6530
  10. 24 7月, 2014 1 次提交
    • C
      arm64: Fix barriers used for page table modifications · 7f0b1bf0
      Catalin Marinas 提交于
      The architecture specification states that both DSB and ISB are required
      between page table modifications and subsequent memory accesses using the
      corresponding virtual address. When TLB invalidation takes place, the
      tlb_flush_* functions already have the necessary barriers. However, there are
      other functions like create_mapping() for which this is not the case.
      
      The patch adds the DSB+ISB instructions in the set_pte() function for
      valid kernel mappings. The invalid pte case is handled by tlb_flush_*
      and the user mappings in general have a corresponding update_mmu_cache()
      call containing a DSB. Even when update_mmu_cache() isn't called, the
      kernel can still cope with an unlikely spurious page fault by
      re-executing the instruction.
      
      In addition, the set_pmd, set_pud() functions gain an ISB for
      architecture compliance when block mappings are created.
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      Reported-by: NLeif Lindholm <leif.lindholm@linaro.org>
      Acked-by: NSteve Capper <steve.capper@linaro.org>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: <stable@vger.kernel.org>
      7f0b1bf0
  11. 10 5月, 2014 2 次提交
  12. 14 6月, 2013 1 次提交
  13. 17 9月, 2012 1 次提交