1. 30 Jul, 2012 1 commit
  2. 09 Jul, 2011 3 commits
    • Russell King's avatar
      ARM: vfp: fix a hole in VFP thread migration · f8f2a852
      Russell King authored
      
      
      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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      f8f2a852
    • Russell King's avatar
      ARM: vfp: rename check_exception to vfp_hw_state_valid · 08409c33
      Russell King authored
      
      
      Rename this branch to more accurately reflect why its taken, rather
      than what the following code does.  It is the only caller of this code.
      This helps to clarify following changes, yet this change results in no
      actual code change.
      
      Document the VFP hardware state at the target of this branch.
      
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      08409c33
    • Russell King's avatar
      ARM: vfp: rename last_VFP_context to vfp_current_hw_state · af61bdf0
      Russell King authored
      
      
      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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      af61bdf0
  3. 30 Nov, 2010 1 commit
    • Dave Martin's avatar
      ARM: 6498/1: vfp: Correct data alignment for CONFIG_THUMB2_KERNEL · 7eb25ebe
      Dave Martin authored
      
      
      Directives such as .long and .word do not magically cause the
      assembler location counter to become aligned in gas.  As a result,
      using these directives in code sections can result in misaligned
      data words when building a Thumb-2 kernel (CONFIG_THUMB2_KERNEL).
      
      This is a Bad Thing, since the ABI permits the compiler to assume
      that fundamental types of word size or above are word- aligned when
      accessing them from C.  If the data is not really word-aligned,
      this can cause impaired performance and stray alignment faults in
      some circumstances.
      
      In general, the following rules should be applied when using data
      word declaration directives inside code sections:
      
          * .quad and .double:
               .align 3
      
          * .long, .word, .single, .float:
               .align (or .align 2)
      
          * .short:
              No explicit alignment required, since Thumb-2
              instructions are always 2 or 4 bytes in size.
              immediately after an instruction.
      
      Reviewed-by: default avatarWill Deacon <will.deacon@arm.com>
      Signed-off-by: default avatarDave Martin <dave.martin@linaro.org>
      Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      7eb25ebe
  4. 27 May, 2010 1 commit
  5. 24 Jul, 2009 1 commit
  6. 30 May, 2009 1 commit
    • Catalin Marinas's avatar
      Fix the VFP handling on the Feroceon CPU · 85d6943a
      Catalin Marinas authored
      
      
      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: default avatarCatalin Marinas <catalin.marinas@arm.com>
      Cc: Nicolas Pitre <nico@cam.org>
      85d6943a
  7. 01 Apr, 2009 1 commit
  8. 12 Feb, 2009 1 commit
  9. 18 Dec, 2008 1 commit
    • Ben Dooks's avatar
      [ARM] 5349/1: VFP: Add PM code to save and restore current VFP state · fc0b7a20
      Ben Dooks authored
      
      
      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: default avatarBen Dooks <ben-linux@fluff.org>
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      fc0b7a20
  10. 06 Nov, 2008 1 commit
  11. 01 Sep, 2008 1 commit
  12. 26 Jan, 2008 2 commits
    • Catalin Marinas's avatar
      [ARM] 4583/1: ARMv7: Add VFPv3 support · 25ebee02
      Catalin Marinas authored
      
      
      This patch adds the support for VFPv3 (the kernel currently supports
      VFPv2). The main difference is 32 double registers (compared to 16).
      
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      25ebee02
    • Catalin Marinas's avatar
      [ARM] 4582/2: Add support for the common VFP subarchitecture · c98929c0
      Catalin Marinas authored
      
      
      This patch allows the VFP support code to run correctly on CPUs
      compatible with the common VFP subarchitecture specification (Appendix
      B in the ARM ARM v7-A and v7-R edition). It implements support for VFP
      subarchitecture 2 while being backwards compatible with
      subarchitecture 1.
      
      On VFP subarchitecture 1, the arithmetic exceptions are asynchronous
      (or imprecise as described in the old ARM ARM) unless the FPSCR.IXE
      bit is 1. The exceptional instructions can be read from FPINST and
      FPINST2 registers. With VFP subarchitecture 2, the arithmetic
      exceptions can also be synchronous and marked by the FPEXC.DEX bit
      (the FPEXC.EX bit is cleared). CPUs implementing the synchronous
      arithmetic exceptions don't have the FPINST and FPINST2 registers and
      accessing them would trigger and undefined exception.
      
      Note that FPEXC.EX bit has an additional meaning on subarchitecture 1
      - if it isn't set, there is no additional information in FPINST and
      FPINST2 that needs to be saved at context switch or when lazy-loading
      the VFP state of a different thread.
      
      The patch also removes the clearing of the cumulative exception flags in
      FPSCR when additional exceptions were raised. It is up to the user
      application to clear these bits.
      
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      c98929c0
  13. 20 Jul, 2007 1 commit
  14. 25 Jan, 2007 1 commit
  15. 30 Aug, 2006 1 commit
  16. 22 Jun, 2006 1 commit
    • Russell King's avatar
      [ARM] Enable VFP to be built when non-VFP capable CPUs are selected · 1a6be26d
      Russell King authored
      
      
      Since we pass flags to the compiler to control code generation based
      on the least capable selected CPU, if we want to include VFP support,
      we must tweak the assembler flags to allow the VFP instructions.
      Moreover, we must not use the mrrc/mcrr versions since these will not
      be recognised by the assembler.
      
      We do not convert all instructions to the VFP-equivalent (yet) since
      binutils appears to barf on "fmrx rn, fpinst" and doesn't provide any
      other way (other than using the mrc equivalent) to encode this
      instruction - which is rather a problem when you have a VFP
      implementation which requires these instructions.
      
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      1a6be26d
  17. 10 Apr, 2006 1 commit
  18. 25 Mar, 2006 1 commit
  19. 16 Apr, 2005 1 commit
    • Linus Torvalds's avatar
      Linux-2.6.12-rc2 · 1da177e4
      Linus Torvalds authored
      Initial git repository build. I'm not bothering with the full history,
      even though we have it. We can create a separate "historical" git
      archive of that later if we want to, and in the meantime it's about
      3.2GB when imported into git - space that would just make the early
      git days unnecessarily complicated, when we don't have a lot of good
      infrastructure for it.
      
      Let it rip!
      1da177e4