1. 22 6月, 2013 1 次提交
  2. 25 5月, 2013 1 次提交
    • V
      ARC: lazy dcache flush broke gdb in non-aliasing configs · 7bb66f6e
      Vineet Gupta 提交于
      gdbserver inserting a breakpoint ends up calling copy_user_page() for a
      code page. The generic version of which (non-aliasing config) didn't set
      the PG_arch_1 bit hence update_mmu_cache() didn't sync dcache/icache for
      corresponding dynamic loader code page - causing garbade to be executed.
      
      So now aliasing versions of copy_user_highpage()/clear_page() are made
      default. There is no significant overhead since all of special alias
      handling code is compiled out for non-aliasing build
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      7bb66f6e
  3. 23 5月, 2013 3 次提交
    • V
      ARC: Brown paper bag bug in macro for checking cache color · 3e87974d
      Vineet Gupta 提交于
      The VM_EXEC check in update_mmu_cache() was getting optimized away
      because of a stupid error in definition of macro addr_not_cache_congruent()
      
      The intention was to have the equivalent of following:
      
      	if (a || (1 ? b : 0))
      
      but we ended up with following:
      
      	if (a || 1 ? b : 0)
      
      And because precedence of '||' is more that that of '?', gcc was optimizing
      away evaluation of <a>
      
      Nasty Repercussions:
      1. For non-aliasing configs it would mean some extraneous dcache flushes
         for non-code pages if U/K mappings were not congruent.
      2. For aliasing config, some needed dcache flush for code pages might
         be missed if U/K mappings were congruent.
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      3e87974d
    • V
      ARC: copy_(to|from)_user() to honor usermode-access permissions · a950549c
      Vineet Gupta 提交于
      This manifested as grep failing psuedo-randomly:
      
      -------------->8---------------------
      [ARCLinux]$ ip address show lo | grep inet
      [ARCLinux]$ ip address show lo | grep inet
      [ARCLinux]$ ip address show lo | grep inet
      [ARCLinux]$
      [ARCLinux]$ ip address show lo | grep inet
          inet 127.0.0.1/8 scope host lo
      -------------->8---------------------
      
      ARC700 MMU provides fully orthogonal permission bits per page:
      Ur, Uw, Ux, Kr, Kw, Kx
      
      The user mode page permission templates used to have all Kernel mode
      access bits enabled.
      This caused a tricky race condition observed with uClibc buffered file
      read and UNIX pipes.
      
      1. Read access to an anon mapped page in libc .bss: write-protected
         zero_page mapped: TLB Entry installed with Ur + K[rwx]
      
      2. grep calls libc:getc() -> buffered read layer calls read(2) with the
         internal read buffer in same .bss page.
         The read() call is on STDIN which has been redirected to a pipe.
         read(2) => sys_read() => pipe_read() => copy_to_user()
      
      3. Since page has Kernel-write permission (despite being user-mode
         write-protected), copy_to_user() suceeds w/o taking a MMU TLB-Miss
         Exception (page-fault for ARC). core-MM is unaware that kernel
         erroneously wrote to the reserved read-only zero-page (BUG #1)
      
      4. Control returns to userspace which now does a write to same .bss page
         Since Linux MM is not aware that page has been modified by kernel, it
         simply reassigns a new writable zero-init page to mapping, loosing the
         prior write by kernel - effectively zero'ing out the libc read buffer
         under the hood - hence grep doesn't see right data (BUG #2)
      
      The fix is to make all kernel-mode access permissions mirror the
      user-mode ones. Note that the kernel still has full access to pages,
      when accessed directly (w/o MMU) - this fix ensures that kernel-mode
      access in copy_to_from() path uses the same faulting access model as for
      pure user accesses to keep MM fully aware of page state.
      
      The issue is peudo-random because it only shows up if the TLB entry
      installed in #1 is present at the time of #3. If it is evicted out, due
      to TLB pressure or some-such, then copy_to_user() does take a TLB Miss
      Exception, with a routine write-to-anon COW processing installing a
      fresh page for kernel writes and also usable as it is in userspace.
      
      Further the issue was dormant for so long as it depends on where the
      libc internal read buffer (in .bss) is mapped at runtime.
      If it happens to reside in file-backed data mapping of libc (in the
      page-aligned slack space trailing the file backed data), loader zero
      padding the slack space, does the early cow page replacement, setting
      things up at the very beginning itself.
      
      With gcc 4.8 based builds, the libc buffer got pushed out to a real
      anon mapping which triggers the issue.
      Reported-by: NAnton Kolesov <akolesov@synopsys.com>
      Cc: <stable@vger.kernel.org> # 3.9
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      a950549c
    • V
      ARC: [mm] Prevent stray dcache lines after__sync_icache_dcach() · f538881c
      Vineet Gupta 提交于
      Flush and INVALIDATE the dcache page.
      
      This helper is only used for writeback of CODE pages to memory. So
      there's no value in keeping the dcache lines around. Infact it is risky
      as a writeback on natural eviction under pressure can cause un-needed
      writeback with weird issues on aliasing dcache configurations.
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      f538881c
  4. 10 5月, 2013 4 次提交
  5. 09 5月, 2013 2 次提交
  6. 07 5月, 2013 7 次提交
    • V
      ARC: [mm] Lazy D-cache flush (non aliasing VIPT) · eacd0e95
      Vineet Gupta 提交于
      flush_dcache_page( ) is MM hook to ensure that a page has consistent
      views between kernel and userspace. Thus it is called when
      
      * kernel writes to a page which at some later point could get mapped to
        userspace (so kernel mapping needs to be flushed-n-inv)
      * kernel is about to read from a page with possible userspace mappings
        (so userspace mappings needs to be made coherent with kernel ones)
      
      However for Non aliasing VIPT dcache, any userspace mapping will always
      be congruent to kernel mapping. Thus d-cache need need not be flushed at
      all (or delayed indefinitely).
      
      The only reason it does need to be flushed is when mapping code pages.
      Since icache doesn't snoop dcache, those dirty dcache lines need to be
      written back to memory and icache line invalidated so that icache lines
      fetch will get the right data.
      
      Decent gains on LMBench fork/exec/sh and File I/O micro-benchmarks.
      
      (1) FPGA @ 80 MHZ
      
      Processor, Processes - times in microseconds - smaller is better
      ------------------------------------------------------------------------------
      Host                 OS  Mhz null null      open slct sig  sig  fork exec sh
                                   call  I/O stat clos TCP  inst hndl proc proc proc
      --------- ------------- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
      3.9-rc6-a Linux 3.9.0-r   80 4.79 8.72 66.7 116. 239. 8.39 30.4 4798 14.K 34.K
      3.9-rc6-b Linux 3.9.0-r   80 4.79 8.62 65.4 111. 239. 8.35 29.0 3995 12.K 30.K
      3.9-rc7-c Linux 3.9.0-r   80 4.79 9.00 66.1 106. 239. 8.61 30.4 2858 10.K 24.K
                                                                      ^^^^ ^^^^ ^^^
      
      File & VM system latencies in microseconds - smaller is better
      -------------------------------------------------------------------------------
      Host                 OS   0K File      10K File     Mmap    Prot   Page 100fd
                              Create Delete Create Delete Latency Fault  Fault selct
      --------- ------------- ------ ------ ------ ------ ------- ----- ------- -----
      3.9-rc6-a Linux 3.9.0-r  317.8  204.2 1122.3  375.1 3522.0 4.288     20.7 126.8
      3.9-rc6-b Linux 3.9.0-r  298.7  223.0 1141.6  367.8 3531.0 4.866     20.9 126.4
      3.9-rc7-c Linux 3.9.0-r  278.4  179.2  862.1  339.3 3705.0 3.223     20.3 126.6
                               ^^^^^  ^^^^^  ^^^^^  ^^^^
      
      (2) Customer Silicon @ 500 MHz (166 MHz mem)
      
      ------------------------------------------------------------------------------
      Host                 OS  Mhz null null      open slct sig  sig  fork exec sh
                                   call  I/O stat clos TCP  inst hndl proc proc proc
      --------- ------------- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
      abilis-ba Linux 3.9.0-r  497 0.71 1.38 4.58 12.0 35.5 1.40 3.89 2070 5525 13.K
      abilis-ca Linux 3.9.0-r  497 0.71 1.40 4.61 11.8 35.6 1.37 3.92 1411 4317 10.K
                                                                      ^^^^ ^^^^ ^^^
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      eacd0e95
    • V
      ARC: [mm] micro-optimize page size icache invalidate · 764531cc
      Vineet Gupta 提交于
      start address is already page aligned and size is const PAGE_SIZE,
      thus fixups for alignment not needed in generated code.
      
      bloat-o-meter vmlinux-mm5 vmlinux
      add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-32 (-32)
      function                                     old     new   delta
      __inv_icache_page                             82      50     -32
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      764531cc
    • V
      ARC: [mm] remove the pessimistic all-alias-invalidate icache helpers · 7f250a0f
      Vineet Gupta 提交于
      No users of this code anymore - so RIP !
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      7f250a0f
    • V
      ARC: [mm] consolidate icache/dcache sync code · 94bad1af
      Vineet Gupta 提交于
      Now that we have same helper used for all icache invalidates (i.e.
      vaddr+paddr based exact line invalidate), consolidate the open coded
      calls into one place.
      
      Also rename flush_icache_range_vaddr => __sync_icache_dcache
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      94bad1af
    • V
      ARC: [mm] optimise icache flush for kernel mappings · 7586bf72
      Vineet Gupta 提交于
      This change continues the theme from prev commit - this time icache
      handling for kernel's own code modification (vmalloc: loadable modules,
      breakpoints for kprobes/kgdb...)
      
      flush_icache_range() calls the CDU icache helper with vaddr to enable
      exact line invalidate.
      
      For a true kernel-virtual mapping, the vaddr is actually virtual hence
      valid as index into cache. For kprobes breakpoint however, the vaddr arg
      is actually paddr - since that's how normal kernel is mapped in ARC
      memory map.  This implies that CDU will use the same addr for
      indexing as for tag match - which is fine since kernel code would only
      have that "implicit" mapping and none other.
      
      This should speed up module loading significantly - specially on default
      ARC700 icache configurations (32k) which alias.
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      7586bf72
    • V
      ARC: [mm] optimise icache flush for user mappings · 24603fdd
      Vineet Gupta 提交于
      ARC icache doesn't snoop dcache thus executable pages need to be made
      coherent before mapping into userspace in flush_icache_page().
      
      However ARC700 CDU (hardware cache flush module) requires both vaddr
      (index in cache) as well as paddr (tag match) to correctly identify a
      line in the VIPT cache. A typical ARC700 SoC has aliasing icache, thus
      the paddr only based flush_icache_page() API couldn't be implemented
      efficiently. It had to loop thru all possible alias indexes and perform
      the invalidate operation (ofcourse the cache op would only succeed at
      the index(es) where tag matches - typically only 1, but the cost of
      visiting all the cache-bins needs to paid nevertheless).
      
      Turns out however that the vaddr (along with paddr) is available in
      update_mmu_cache() hence better suits ARC icache flush semantics.
      With both vaddr+paddr, exactly one flush operation per line is done.
      Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
      24603fdd
    • N
      e3edeb67
  7. 30 4月, 2013 1 次提交
  8. 09 4月, 2013 5 次提交
  9. 16 2月, 2013 15 次提交
  10. 11 2月, 2013 1 次提交