1. 29 10月, 2012 1 次提交
    • P
      ARM: 7566/1: vfp: fix save and restore when running on pre-VFPv3 and CONFIG_VFPv3 set · 39141ddf
      Paul Walmsley 提交于
      After commit 846a1368 ("ARM: vfp: fix
      saving d16-d31 vfp registers on v6+ kernels"), the OMAP 2430SDP board
      started crashing during boot with omap2plus_defconfig:
      
      [    3.875122] mmcblk0: mmc0:e624 SD04G 3.69 GiB
      [    3.915954]  mmcblk0: p1
      [    4.086639] Internal error: Oops - undefined instruction: 0 [#1] SMP ARM
      [    4.093719] Modules linked in:
      [    4.096954] CPU: 0    Not tainted  (3.6.0-02232-g759e00b8 #570)
      [    4.103149] PC is at vfp_reload_hw+0x1c/0x44
      [    4.107666] LR is at __und_usr_fault_32+0x0/0x8
      
      It turns out that the context save/restore fix unmasked a latent bug
      in commit 5aaf2544 ("ARM: 6203/1: Make
      VFPv3 usable on ARMv6").  When CONFIG_VFPv3 is set, but the kernel is
      booted on a pre-VFPv3 core, the code attempts to save and restore the
      d16-d31 VFP registers.  These are only present on non-D16 VFPv3+, so
      this results in an undefined instruction exception.  The code didn't
      crash before commit 846a1368 because the save and restore code was
      only touching d0-d15, present on all VFP.
      
      Fix by implementing a request from Russell King to add a new HWCAP
      flag that affirmatively indicates the presence of the d16-d31
      registers:
      
         http://marc.info/?l=linux-arm-kernel&m=135013547905283&w=2
      
      and some feedback from Måns to clarify the name of the HWCAP flag.
      Signed-off-by: NPaul Walmsley <paul@pwsan.com>
      Cc: Tony Lindgren <tony@atomide.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Dave Martin <dave.martin@linaro.org>
      Cc: Måns Rullgård <mans.rullgard@linaro.org>
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      39141ddf
  2. 11 8月, 2012 1 次提交
  3. 31 7月, 2012 2 次提交
    • C
      ARM: 7477/1: vfp: Always save VFP state in vfp_pm_suspend on UP · 24b35521
      Colin Cross 提交于
      vfp_pm_suspend should save the VFP state in suspend after
      any lazy context switch.  If it only saves when the VFP is enabled,
      the state can get lost when, on a UP system:
        Thread 1 uses the VFP
        Context switch occurs to thread 2, VFP is disabled but the
           VFP context is not saved
        Thread 2 initiates suspend
        vfp_pm_suspend is called with the VFP disabled, and the unsaved
           VFP context of Thread 1 in the registers
      
      Modify vfp_pm_suspend to save the VFP context whenever
      vfp_current_hw_state is not NULL.
      
      Includes a fix from Ido Yariv <ido@wizery.com>, who pointed out that on
      SMP systems, the state pointer can be pointing to a freed task struct if
      a task exited on another cpu, fixed by using #ifndef CONFIG_SMP in the
      new if clause.
      
      Cc: Barry Song <bs14@csr.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Ido Yariv <ido@wizery.com>
      Cc: Daniel Drake <dsd@laptop.org>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: NColin Cross <ccross@android.com>
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      24b35521
    • C
      ARM: 7476/1: vfp: only clear vfp state for current cpu in vfp_pm_suspend · a84b895a
      Colin Cross 提交于
      vfp_pm_suspend runs on each cpu, only clear the hardware state
      pointer for the current cpu.  Prevents a possible crash if one
      cpu clears the hw state pointer when another cpu has already
      checked if it is valid.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NColin Cross <ccross@android.com>
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      a84b895a
  4. 17 5月, 2012 1 次提交
    • W
      ARM: 7419/1: vfp: fix VFP flushing regression on sigreturn path · 56cb2484
      Will Deacon 提交于
      Commit ff9a184c ("ARM: 7400/1: vfp: clear fpscr length and stride bits
      on entry to sig handler") flushes the VFP state prior to entering a
      signal handler so that a VFP operation inside the handler will trap and
      force a restore of ABI-compliant registers. Reflushing and disabling VFP
      on the sigreturn path is predicated on the saved thread state indicating
      that VFP was used by the handler -- however for SMP platforms this is
      only set on context-switch, making the check unreliable and causing VFP
      register corruption in userspace since the register values are not
      necessarily those restored from the sigframe.
      
      This patch unconditionally flushes the VFP state after a signal handler.
      Since we already perform the flush before the handler and the flushing
      itself happens lazily, the redundant flush when VFP is not used by the
      handler is essentially a nop.
      Reported-by: NJon Medhurst <tixy@linaro.org>
      Signed-off-by: NJon Medhurst <tixy@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      56cb2484
  5. 12 5月, 2012 2 次提交
  6. 23 4月, 2012 2 次提交
  7. 29 3月, 2012 2 次提交
  8. 24 3月, 2012 1 次提交
  9. 01 11月, 2011 1 次提交
  10. 23 9月, 2011 2 次提交
  11. 10 7月, 2011 3 次提交
    • R
      ARM: vfp: ensure that thread flushing works if preempted · 19dad35f
      Russell King 提交于
      Prevent a preemption event causing the initialized VFP state being
      overwritten by ensuring that the VFP hardware access is disabled
      prior to starting initialization.  We can then do this in safety
      while still allowing preemption to occur.
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      19dad35f
    • R
      ARM: vfp: fix a hole in VFP thread migration · f8f2a852
      Russell King 提交于
      Fix a hole in the VFP thread migration.  Lets define two threads.
      
      Thread 1, we'll call 'interesting_thread' which is a thread which is
      running on CPU0, using VFP (so vfp_current_hw_state[0] =
      &interesting_thread->vfpstate) and gets migrated off to CPU1, where
      it continues execution of VFP instructions.
      
      Thread 2, we'll call 'new_cpu0_thread' which is the thread which takes
      over on CPU0.  This has also been using VFP, and last used VFP on CPU0,
      but doesn't use it again.
      
      The following code will be executed twice:
      
      		cpu = thread->cpu;
      
      		/*
      		 * On SMP, if VFP is enabled, save the old state in
      		 * case the thread migrates to a different CPU. The
      		 * restoring is done lazily.
      		 */
      		if ((fpexc & FPEXC_EN) && vfp_current_hw_state[cpu]) {
      			vfp_save_state(vfp_current_hw_state[cpu], fpexc);
      			vfp_current_hw_state[cpu]->hard.cpu = cpu;
      		}
      		/*
      		 * Thread migration, just force the reloading of the
      		 * state on the new CPU in case the VFP registers
      		 * contain stale data.
      		 */
      		if (thread->vfpstate.hard.cpu != cpu)
      			vfp_current_hw_state[cpu] = NULL;
      
      The first execution will be on CPU0 to switch away from 'interesting_thread'.
      interesting_thread->cpu will be 0.
      
      So, vfp_current_hw_state[0] points at interesting_thread->vfpstate.
      The hardware state will be saved, along with the CPU number (0) that
      it was executing on.
      
      'thread' will be 'new_cpu0_thread' with new_cpu0_thread->cpu = 0.
      Also, because it was executing on CPU0, new_cpu0_thread->vfpstate.hard.cpu = 0,
      and so the thread migration check is not triggered.
      
      This means that vfp_current_hw_state[0] remains pointing at interesting_thread.
      
      The second execution will be on CPU1 to switch _to_ 'interesting_thread'.
      So, 'thread' will be 'interesting_thread' and interesting_thread->cpu now
      will be 1.  The previous thread executing on CPU1 is not relevant to this
      so we shall ignore that.
      
      We get to the thread migration check.  Here, we discover that
      interesting_thread->vfpstate.hard.cpu = 0, yet interesting_thread->cpu is
      now 1, indicating thread migration.  We set vfp_current_hw_state[1] to
      NULL.
      
      So, at this point vfp_current_hw_state[] contains the following:
      
      [0] = &interesting_thread->vfpstate
      [1] = NULL
      
      Our interesting thread now executes a VFP instruction, takes a fault
      which loads the state into the VFP hardware.  Now, through the assembly
      we now have:
      
      [0] = &interesting_thread->vfpstate
      [1] = &interesting_thread->vfpstate
      
      CPU1 stops due to ptrace (and so saves its VFP state) using the thread
      switch code above), and CPU0 calls vfp_sync_hwstate().
      
      	if (vfp_current_hw_state[cpu] == &thread->vfpstate) {
      		vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN);
      
      BANG, we corrupt interesting_thread's VFP state by overwriting the
      more up-to-date state saved by CPU1 with the old VFP state from CPU0.
      
      Fix this by ensuring that we have sane semantics for the various state
      describing variables:
      
      1. vfp_current_hw_state[] points to the current owner of the context
         information stored in each CPUs hardware, or NULL if that state
         information is invalid.
      2. thread->vfpstate.hard.cpu always contains the most recent CPU number
         which the state was loaded into or NR_CPUS if no CPU owns the state.
      
      So, for a particular CPU to be a valid owner of the VFP state for a
      particular thread t, two things must be true:
      
       vfp_current_hw_state[cpu] == &t->vfpstate && t->vfpstate.hard.cpu == cpu.
      
      and that is valid from the moment a CPU loads the saved VFP context
      into the hardware.  This gives clear and consistent semantics to
      interpreting these variables.
      
      This patch also fixes thread copying, ensuring that t->vfpstate.hard.cpu
      is invalidated, otherwise CPU0 may believe it was the last owner.  The
      hole can happen thus:
      
      - thread1 runs on CPU2 using VFP, migrates to CPU3, exits and thread_info
        freed.
      - New thread allocated from a previously running thread on CPU2, reusing
        memory for thread1 and copying vfp.hard.cpu.
      
      At this point, the following are true:
      
      	new_thread1->vfpstate.hard.cpu == 2
      	&new_thread1->vfpstate == vfp_current_hw_state[2]
      
      Lastly, this also addresses thread flushing in a similar way to thread
      copying.  Hole is:
      
      - thread runs on CPU0, using VFP, migrates to CPU1 but does not use VFP.
      - thread calls execve(), so thread flush happens, leaving
        vfp_current_hw_state[0] intact.  This vfpstate is memset to 0 causing
        thread->vfpstate.hard.cpu = 0.
      - thread migrates back to CPU0 before using VFP.
      
      At this point, the following are true:
      
      	thread->vfpstate.hard.cpu == 0
      	&thread->vfpstate == vfp_current_hw_state[0]
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      f8f2a852
    • R
      ARM: vfp: rename last_VFP_context to vfp_current_hw_state · af61bdf0
      Russell King 提交于
      Rename the slightly confusing 'last_VFP_context' variable to be more
      descriptive of what it actually is.  This variable stores a pointer
      to the current owner's vfpstate structure for the context held in the
      VFP hardware.
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      af61bdf0
  12. 08 7月, 2011 1 次提交
  13. 25 4月, 2011 1 次提交
  14. 11 4月, 2011 2 次提交
  15. 24 2月, 2011 2 次提交
  16. 20 12月, 2010 1 次提交
  17. 09 7月, 2010 1 次提交
  18. 14 4月, 2010 1 次提交
  19. 28 3月, 2010 1 次提交
  20. 16 2月, 2010 2 次提交
    • R
      ARM: vfp ptrace: no point flushing hw context for PTRACE_GETVFPREGS · ad187f95
      Russell King 提交于
      If we're only reading the VFP context via the ptrace call, there's
      no need to invalidate the hardware context - we only need to do that
      on PTRACE_SETVFPREGS.  This allows more efficient monitoring of a
      traced task.
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      ad187f95
    • R
      ARM: vfp: fix vfp_sync_state() · 54cb3dbb
      Russell King 提交于
      The more I look at vfp_sync_state(), the more I believe it's trying
      to do its job in a really obscure way.
      
      Essentially, last_VFP_context[] tracks who owns the state in the VFP
      hardware.  If last_VFP_context[] is the context for the thread which
      we're interested in, then the VFP hardware has context which is not
      saved in the software state - so we need to bring the software state
      up to date.
      
      If last_VFP_context[] is for some other thread, we really don't care
      what state the VFP hardware is in; it doesn't contain any information
      pertinent to the thread we're trying to deal with - so don't touch
      the hardware.
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      54cb3dbb
  21. 02 2月, 2010 1 次提交
  22. 18 12月, 2009 1 次提交
  23. 14 12月, 2009 1 次提交
    • R
      ARM: VFP: fix vfp thread init bug and document vfp notifier entry conditions · 0d782dc4
      Russell King 提交于
      When the VFP notifier is called for flush_thread(), we may be
      preemptible, meaning we might migrate to another CPU, which means
      referencing the current CPU number without some form of locking is
      invalid, and can cause data corruption.
      
      For the most cases, this isn't a problem since atomic notifiers are run
      under rcu lock, which for most configurations results in preemption
      being disabled - except when the preemptable tree-based rcu
      implementation is selected.
      
      Let's make it safe anyway.
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      0d782dc4
  24. 30 5月, 2009 1 次提交
    • C
      Fix the VFP handling on the Feroceon CPU · 85d6943a
      Catalin Marinas 提交于
      This CPU generates synchronous VFP exceptions in a non-standard way -
      the FPEXC.EX bit set but without the FPSCR.IXE bit being set like in the
      VFP subarchitecture 1 or just the FPEXC.DEX bit like in VFP
      subarchitecture 2. The main problem is that the faulty instruction
      (which needs to be emulated in software) will be restarted several times
      (normally until a context switch disables the VFP). This patch ensures
      that the VFP exception is treated as synchronous.
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Nicolas Pitre <nico@cam.org>
      85d6943a
  25. 02 4月, 2009 1 次提交
  26. 12 2月, 2009 2 次提交
  27. 19 12月, 2008 1 次提交
    • B
      [ARM] 5349/1: VFP: Add PM code to save and restore current VFP state · fc0b7a20
      Ben Dooks 提交于
      When CONFIG_PM is selected, the VFP code does not have any handler
      installed to deal with either saving the VFP state of the current
      task, nor does it do anything to try and restore the VFP after a
      resume.
      
      On resume, the VFP will have been reset and the co-processor access
      control registers are in an indeterminate state (very probably the
      CP10 and CP11 the VFP uses will have been disabled by the ARM core
      reset). When this happens, resume will break as soon as it tries to
      unfreeze the tasks and restart scheduling.
      
      Add a sys device to allow us to hook the suspend call to save the
      current thread state if the thread is using VFP and a resume hook
      which restores the CP10/CP11 access and ensures the VFP is disabled
      so that the lazy swapping will take place on next access.
      Signed-off-by: NBen Dooks <ben-linux@fluff.org>
      Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
      fc0b7a20
  28. 06 11月, 2008 1 次提交
  29. 26 6月, 2008 1 次提交