1. 04 9月, 2017 1 次提交
  2. 25 2月, 2017 1 次提交
  3. 21 9月, 2016 1 次提交
    • J
      MIPS: vDSO: Fix Malta EVA mapping to vDSO page structs · 554af0c3
      James Hogan 提交于
      The page structures associated with the vDSO pages in the kernel image
      are calculated using virt_to_page(), which uses __pa() under the hood to
      find the pfn associated with the virtual address. The vDSO data pointers
      however point to kernel symbols, so __pa_symbol() should really be used
      instead.
      
      Since there is no equivalent to virt_to_page() which uses __pa_symbol(),
      fix init_vdso_image() to work directly with pfns, calculated with
      __phys_to_pfn(__pa_symbol(...)).
      
      This issue broke the Malta Enhanced Virtual Addressing (EVA)
      configuration which has a non-default implementation of __pa_symbol().
      This is because it uses a physical alias so that the kernel executes
      from KSeg0 (VA 0x80000000 -> PA 0x00000000), while RAM is provided to
      the kernel in the KUSeg range (VA 0x00000000 -> PA 0x80000000) which
      uses the same underlying RAM.
      
      Since there are no page structures associated with the low physical
      address region, some arbitrary kernel memory would be interpreted as a
      page structure for the vDSO pages and badness ensues.
      
      Fixes: ebb5e78c ("MIPS: Initial implementation of a VDSO")
      Signed-off-by: NJames Hogan <james.hogan@imgtec.com>
      Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
      Cc: linux-mips@linux-mips.org
      Cc: <stable@vger.kernel.org> # 4.4.x-
      Patchwork: https://patchwork.linux-mips.org/patch/14229/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
      554af0c3
  4. 02 8月, 2016 1 次提交
    • P
      MIPS: Use per-mm page to execute branch delay slot instructions · 432c6bac
      Paul Burton 提交于
      In some cases the kernel needs to execute an instruction from the delay
      slot of an emulated branch instruction. These cases include:
      
        - Emulated floating point branch instructions (bc1[ft]l?) for systems
          which don't include an FPU, or upon which the kernel is run with the
          "nofpu" parameter.
      
        - MIPSr6 systems running binaries targeting older revisions of the
          architecture, which may include branch instructions whose encodings
          are no longer valid in MIPSr6.
      
      Executing instructions from such delay slots is done by writing the
      instruction to memory followed by a trap, as part of an "emuframe", and
      executing it. This avoids the requirement of an emulator for the entire
      MIPS instruction set. Prior to this patch such emuframes are written to
      the user stack and executed from there.
      
      This patch moves FP branch delay emuframes off of the user stack and
      into a per-mm page. Allocating a page per-mm leaves userland with access
      to only what it had access to previously, and compared to other
      solutions is relatively simple.
      
      When a thread requires a delay slot emulation, it is allocated a frame.
      A thread may only have one frame allocated at any one time, since it may
      only ever be executing one instruction at any one time. In order to
      ensure that we can free up allocated frame later, its index is recorded
      in struct thread_struct. In the typical case, after executing the delay
      slot instruction we'll execute a break instruction with the BRK_MEMU
      code. This traps back to the kernel & leads to a call to do_dsemulret
      which frees the allocated frame & moves the user PC back to the
      instruction that would have executed following the emulated branch.
      In some cases the delay slot instruction may be invalid, such as a
      branch, or may trigger an exception. In these cases the BRK_MEMU break
      instruction will not be hit. In order to ensure that frames are freed
      this patch introduces dsemul_thread_cleanup() and calls it to free any
      allocated frame upon thread exit. If the instruction generated an
      exception & leads to a signal being delivered to the thread, or indeed
      if a signal simply happens to be delivered to the thread whilst it is
      executing from the struct emuframe, then we need to take care to exit
      the frame appropriately. This is done by either rolling back the user PC
      to the branch or advancing it to the continuation PC prior to signal
      delivery, using dsemul_thread_rollback(). If this were not done then a
      sigreturn would return to the struct emuframe, and if that frame had
      meanwhile been used in response to an emulated branch instruction within
      the signal handler then we would execute the wrong user code.
      
      Whilst a user could theoretically place something like a compact branch
      to self in a delay slot and cause their thread to become stuck in an
      infinite loop with the frame never being deallocated, this would:
      
        - Only affect the users single process.
      
        - Be architecturally invalid since there would be a branch in the
          delay slot, which is forbidden.
      
        - Be extremely unlikely to happen by mistake, and provide a program
          with no more ability to harm the system than a simple infinite loop
          would.
      
      If a thread requires a delay slot emulation & no frame is available to
      it (ie. the process has enough other threads that all frames are
      currently in use) then the thread joins a waitqueue. It will sleep until
      a frame is freed by another thread in the process.
      
      Since we now know whether a thread has an allocated frame due to our
      tracking of its index, the cookie field of struct emuframe is removed as
      we can be more certain whether we have a valid frame. Since a thread may
      only ever have a single frame at any given time, the epc field of struct
      emuframe is also removed & the PC to continue from is instead stored in
      struct thread_struct. Together these changes simplify & shrink struct
      emuframe somewhat, allowing twice as many frames to fit into the page
      allocated for them.
      
      The primary benefit of this patch is that we are now free to mark the
      user stack non-executable where that is possible.
      Signed-off-by: NPaul Burton <paul.burton@imgtec.com>
      Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
      Cc: Maciej Rozycki <maciej.rozycki@imgtec.com>
      Cc: Faraz Shahbazker <faraz.shahbazker@imgtec.com>
      Cc: Raghu Gandham <raghu.gandham@imgtec.com>
      Cc: Matthew Fortune <matthew.fortune@imgtec.com>
      Cc: linux-mips@linux-mips.org
      Patchwork: https://patchwork.linux-mips.org/patch/13764/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
      432c6bac
  5. 24 5月, 2016 1 次提交
  6. 11 11月, 2015 2 次提交
    • A
      MIPS: VDSO: Add implementations of gettimeofday() and clock_gettime() · a7f4df4e
      Alex Smith 提交于
      Add user-mode implementations of gettimeofday() and clock_gettime() to
      the VDSO. This is currently usable with 2 clocksources: the CP0 count
      register, which is accessible to user-mode via RDHWR on R2 and later
      cores, or the MIPS Global Interrupt Controller (GIC) timer, which
      provides a "user-mode visible" section containing a mirror of its
      counter registers. This section must be mapped into user memory, which
      is done below the VDSO data page.
      
      When a supported clocksource is not in use, the VDSO functions will
      return -ENOSYS, which causes libc to fall back on the standard syscall
      path.
      
      When support for neither of these clocksources is compiled into the
      kernel at all, the VDSO still provides clock_gettime(), as the coarse
      realtime/monotonic clocks can still be implemented. However,
      gettimeofday() is not provided in this case as nothing can be done
      without a suitable clocksource. This causes the symbol lookup to fail
      in libc and it will then always use the standard syscall path.
      
      This patch includes a workaround for a bug in QEMU which results in
      RDHWR on the CP0 count register always returning a constant (incorrect)
      value. A fix for this has been submitted, and the workaround can be
      removed after the fix has been in stable releases for a reasonable
      amount of time.
      
      A simple performance test which calls gettimeofday() 1000 times in a
      loop and calculates the average execution time gives the following
      results on a Malta + I6400 (running at 20MHz):
      
       - Syscall:    ~31000 ns
       - VDSO (GIC): ~15000 ns
       - VDSO (CP0): ~9500 ns
      
      [markos.chandras@imgtec.com:
      - Minor code re-arrangements in order for mappings to be made
      in the order they appear to the process' address space.
      - Move do_{monotonic, realtime} outside of the MIPS_CLOCK_VSYSCALL ifdef
      - Use gic_get_usm_range so we can do the GIC mapping in the
      arch/mips/kernel/vdso instead of the GIC irqchip driver]
      Signed-off-by: NAlex Smith <alex.smith@imgtec.com>
      Signed-off-by: NMarkos Chandras <markos.chandras@imgtec.com>
      Cc: linux-kernel@vger.kernel.org
      Cc: linux-mips@linux-mips.org
      Patchwork: https://patchwork.linux-mips.org/patch/11338/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
      a7f4df4e
    • A
      MIPS: Initial implementation of a VDSO · ebb5e78c
      Alex Smith 提交于
      Add an initial implementation of a proper (i.e. an ELF shared library)
      VDSO. With this commit it does not export any symbols, it only replaces
      the current signal return trampoline page. A later commit will add user
      implementations of gettimeofday()/clock_gettime().
      
      To support both new toolchains and old ones which don't generate ABI
      flags section, we define its content manually and then use a tool
      (genvdso) to patch up the section to have the correct name and type.
      genvdso also extracts symbol offsets ({,rt_}sigreturn) needed by the
      kernel, and generates a C file containing a "struct mips_vdso_image"
      containing both the VDSO data and these offsets. This C file is
      compiled into the kernel.
      
      On 64-bit kernels we require a different VDSO for each supported ABI,
      so we may build up to 3 different VDSOs. The VDSO to use is selected by
      the mips_abi structure.
      
      A kernel/user shared data page is created and mapped below the VDSO
      image. This is currently empty, but will be used by the user time
      function implementations which are added later.
      
      [markos.chandras@imgtec.com:
      - Add more comments
      - Move abi detection in genvdso.h since it's the get_symbol function
      that needs it.
      - Add an R6 specific way to calculate the base address of VDSO in order
      to avoid the branch instruction which affects performance.
      - Do not patch .gnu.attributes since it's not needed for dynamic linking.
      - Simplify Makefile a little bit.
      - checkpatch fixes
      - Restrict VDSO support for binutils < 2.25 for pre-R6
      - Include atomic64.h for O32 variant on MIPS64]
      Signed-off-by: NAlex Smith <alex.smith@imgtec.com>
      Signed-off-by: NMarkos Chandras <markos.chandras@imgtec.com>
      Cc: Matthew Fortune <matthew.fortune@imgtec.com>
      Cc: linux-mips@linux-mips.org
      Patchwork: https://patchwork.linux-mips.org/patch/11337/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
      ebb5e78c
  7. 24 11月, 2014 1 次提交
    • P
      MIPS: Enable VDSO randomization · ccd39880
      Prem Karat 提交于
      Based on commit 1091458d (mmap randomization)
      
      For 32-bit address spaces randomize within a
      16MB space, for 64-bit within a 256MB space.
      
      Test Results:
      ------------
      Without Patch (VDSO is not randomized)
      ---------------------------------------
      root@Maleo:~# ./aslr vdso
      FAIL: ASLR not functional (vdso always at 0x7fff7000)
      
      root@Maleo:~# ./aslr rekey vdso
      pre_val==cur_val
      value=0x7fff7000
      
      With patch:(VDSO is randmoized and doesn't interfere with stack)
      ----------------------------------------------------------------
      root@cavium-octeon2:~# ./aslr rekey vdso
      pre_val!=cur_val
      previous_value=0x7f830ea2
      current_value=0x776e2000
      root@cavium-octeon2:~# ./aslr rekey vdso
      pre_val!=cur_val
      previous_value=0x7fb0cea2
      current_value=0x77209000
      root@cavium-octeon2:~# ./aslr rekey vdso
      pre_val!=cur_val
      previous_value=0x7f985ea2
      current_value=0x7770c000
      root@cavium-octeon2:~# ./aslr rekey vdso
      pre_val!=cur_val
      previous_value=0x7fbc6ea2
      current_value=0x7fe25000
      
      Maps file output:
      -------------------------
      root@cavium-octeon2:~# ./aslr rekey maps
      78584000-785a5000 rwxp 00000000 00:00 0                                  [heap]
      7f9d0000-7f9f1000 rw-p 00000000 00:00 0                                  [stack]
      7ffa5000-7ffa6000 r-xp 00000000 00:00 0                                  [vdso]
      
      root@cavium-octeon2:~# ./aslr rekey maps
      77de0000-77e01000 rwxp 00000000 00:00 0                                  [heap]
      7f91b000-7f93c000 rw-p 00000000 00:00 0                                  [stack]
      7ff99000-7ff9a000 r-xp 00000000 00:00 0                                  [vdso]
      
      root@cavium-octeon2:~# ./aslr rekey maps
      77d7f000-77da0000 rwxp 00000000 00:00 0                                  [heap]
      7fc2a000-7fc4b000 rw-p 00000000 00:00 0                                  [stack]
      7fe09000-7fe0a000 r-xp 00000000 00:00 0                                  [vdso]
      
      root@cavium-octeon2:~# ./aslr rekey maps
      7794c000-7794d000 r-xp 00000000 00:00 0                                  [vdso]
      77e4b000-77e6c000 rwxp 00000000 00:00 0                                  [heap]
      7f6e7000-7f708000 rw-p 00000000 00:00 0                                  [stack]
      root@cavium-octeon2:~#
      Signed-off-by: NPrem Karat <pkarat@mvista.com>
      Cc: linux-mips@linux-mips.org
      Cc: sergei.shtylyov@cogentembedded.com
      Cc: ddaney.cavm@gmail.com
      Patchwork: https://patchwork.linux-mips.org/patch/6812Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
      ccd39880
  8. 24 3月, 2012 1 次提交
    • J
      coredump: remove VM_ALWAYSDUMP flag · 909af768
      Jason Baron 提交于
      The motivation for this patchset was that I was looking at a way for a
      qemu-kvm process, to exclude the guest memory from its core dump, which
      can be quite large.  There are already a number of filter flags in
      /proc/<pid>/coredump_filter, however, these allow one to specify 'types'
      of kernel memory, not specific address ranges (which is needed in this
      case).
      
      Since there are no more vma flags available, the first patch eliminates
      the need for the 'VM_ALWAYSDUMP' flag.  The flag is used internally by
      the kernel to mark vdso and vsyscall pages.  However, it is simple
      enough to check if a vma covers a vdso or vsyscall page without the need
      for this flag.
      
      The second patch then replaces the 'VM_ALWAYSDUMP' flag with a new
      'VM_NODUMP' flag, which can be set by userspace using new madvise flags:
      'MADV_DONTDUMP', and unset via 'MADV_DODUMP'.  The core dump filters
      continue to work the same as before unless 'MADV_DONTDUMP' is set on the
      region.
      
      The qemu code which implements this features is at:
      
        http://people.redhat.com/~jbaron/qemu-dump/qemu-dump.patch
      
      In my testing the qemu core dump shrunk from 383MB -> 13MB with this
      patch.
      
      I also believe that the 'MADV_DONTDUMP' flag might be useful for
      security sensitive apps, which might want to select which areas are
      dumped.
      
      This patch:
      
      The VM_ALWAYSDUMP flag is currently used by the coredump code to
      indicate that a vma is part of a vsyscall or vdso section.  However, we
      can determine if a vma is in one these sections by checking it against
      the gate_vma and checking for a non-NULL return value from
      arch_vma_name().  Thus, freeing a valuable vma bit.
      Signed-off-by: NJason Baron <jbaron@redhat.com>
      Acked-by: NRoland McGrath <roland@hack.frob.com>
      Cc: Chris Metcalf <cmetcalf@tilera.com>
      Cc: Avi Kivity <avi@redhat.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      909af768
  9. 27 7月, 2010 2 次提交
  10. 13 4月, 2010 1 次提交
    • D
      MIPS: Preliminary VDSO · c52d0d30
      David Daney 提交于
      This is a preliminary patch to add a vdso to all user processes.  Still
      missing are ELF headers and .eh_frame information.  But it is enough to
      allow us to move signal trampolines off of the stack.  Note that emulation
      of branch delay slots in the FPU emulator still requires the stack.
      
      We allocate a single page (the vdso) and write all possible signal
      trampolines into it.  The stack is moved down by one page and the vdso is
      mapped into this space.
      Signed-off-by: NDavid Daney <ddaney@caviumnetworks.com>
      To: linux-mips@linux-mips.org
      Patchwork: http://patchwork.linux-mips.org/patch/975/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
      c52d0d30