1. 25 5月, 2018 8 次提交
    • D
      arm64/sve: Switch sve_pffr() argument from task to thread · 2cf97d46
      Dave Martin 提交于
      sve_pffr(), which is used to derive the base address used for
      low-level SVE save/restore routines, currently takes the relevant
      task_struct as an argument.
      
      The only accessed fields are actually part of thread_struct, so
      this patch changes the argument type accordingly.  This is done in
      preparation for moving this function to a header, where we do not
      want to have to include <linux/sched.h> due to the consequent
      circular #include problems.
      
      No functional change.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      2cf97d46
    • D
      arm64/sve: Move read_zcr_features() out of cpufeature.h · 31dc52b3
      Dave Martin 提交于
      Having read_zcr_features() inline in cpufeature.h results in that
      header requiring #includes which make it hard to include
      <asm/fpsimd.h> elsewhere without triggering header inclusion
      cycles.
      
      This is not a hot-path function and arguably should not be in
      cpufeature.h in the first place, so this patch moves it to
      fpsimd.c, compiled conditionally if CONFIG_ARM64_SVE=y.
      
      This allows some SVE-related #includes to be dropped from
      cpufeature.h, which will ease future maintenance.
      
      A couple of missing #includes of <asm/fpsimd.h> are exposed by this
      change under arch/arm64/.  This patch adds the missing #includes as
      necessary.
      
      No functional change.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      31dc52b3
    • D
      KVM: arm64: Optimise FPSIMD handling to reduce guest/host thrashing · e6b673b7
      Dave Martin 提交于
      This patch refactors KVM to align the host and guest FPSIMD
      save/restore logic with each other for arm64.  This reduces the
      number of redundant save/restore operations that must occur, and
      reduces the common-case IRQ blackout time during guest exit storms
      by saving the host state lazily and optimising away the need to
      restore the host state before returning to the run loop.
      
      Four hooks are defined in order to enable this:
      
       * kvm_arch_vcpu_run_map_fp():
         Called on PID change to map necessary bits of current to Hyp.
      
       * kvm_arch_vcpu_load_fp():
         Set up FP/SIMD for entering the KVM run loop (parse as
         "vcpu_load fp").
      
       * kvm_arch_vcpu_ctxsync_fp():
         Get FP/SIMD into a safe state for re-enabling interrupts after a
         guest exit back to the run loop.
      
         For arm64 specifically, this involves updating the host kernel's
         FPSIMD context tracking metadata so that kernel-mode NEON use
         will cause the vcpu's FPSIMD state to be saved back correctly
         into the vcpu struct.  This must be done before re-enabling
         interrupts because kernel-mode NEON may be used by softirqs.
      
       * kvm_arch_vcpu_put_fp():
         Save guest FP/SIMD state back to memory and dissociate from the
         CPU ("vcpu_put fp").
      
      Also, the arm64 FPSIMD context switch code is updated to enable it
      to save back FPSIMD state for a vcpu, not just current.  A few
      helpers drive this:
      
       * fpsimd_bind_state_to_cpu(struct user_fpsimd_state *fp):
         mark this CPU as having context fp (which may belong to a vcpu)
         currently loaded in its registers.  This is the non-task
         equivalent of the static function fpsimd_bind_to_cpu() in
         fpsimd.c.
      
       * task_fpsimd_save():
         exported to allow KVM to save the guest's FPSIMD state back to
         memory on exit from the run loop.
      
       * fpsimd_flush_state():
         invalidate any context's FPSIMD state that is currently loaded.
         Used to disassociate the vcpu from the CPU regs on run loop exit.
      
      These changes allow the run loop to enable interrupts (and thus
      softirqs that may use kernel-mode NEON) without having to save the
      guest's FPSIMD state eagerly.
      
      Some new vcpu_arch fields are added to make all this work.  Because
      host FPSIMD state can now be saved back directly into current's
      thread_struct as appropriate, host_cpu_context is no longer used
      for preserving the FPSIMD state.  However, it is still needed for
      preserving other things such as the host's system registers.  To
      avoid ABI churn, the redundant storage space in host_cpu_context is
      not removed for now.
      
      arch/arm is not addressed by this patch and continues to use its
      current save/restore logic.  It could provide implementations of
      the helpers later if desired.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Reviewed-by: NChristoffer Dall <christoffer.dall@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      e6b673b7
    • D
      arm64/sve: Refactor user SVE trap maintenance for external use · 0cff8e77
      Dave Martin 提交于
      In preparation for optimising the way KVM manages switching the
      guest and host FPSIMD state, it is necessary to provide a means for
      code outside arch/arm64/kernel/fpsimd.c to restore the user trap
      configuration for SVE correctly for the current task.
      
      Rather than requiring external code to duplicate the maintenance
      explicitly, this patch moves the trap maintenenace to
      fpsimd_bind_to_cpu(), since it is logically part of the work of
      associating the current task with the cpu.
      
      Because fpsimd_bind_to_cpu() is rather a cryptic name to publish
      alongside fpsimd_bind_state_to_cpu(), the former function is
      renamed to fpsimd_bind_task_to_cpu() to make its purpose more
      explicit.
      
      This patch makes appropriate changes to ensure that
      fpsimd_bind_task_to_cpu() is always called alongside
      task_fpsimd_load(), so that the trap maintenance continues to be
      done in every situation where it was done prior to this patch.
      
      As a side-effect, the metadata updates done by
      fpsimd_bind_task_to_cpu() now change from conditional to
      unconditional in the "already bound" case of sigreturn.  This is
      harmless, and a couple of extra stores on this slow path will not
      impact performance.  I consider this a reasonable price to pay for
      a slightly cleaner interface.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      0cff8e77
    • D
      arm64: fpsimd: Eliminate task->mm checks · df3fb968
      Dave Martin 提交于
      Currently the FPSIMD handling code uses the condition task->mm ==
      NULL as a hint that task has no FPSIMD register context.
      
      The ->mm check is only there to filter out tasks that cannot
      possibly have FPSIMD context loaded, for optimisation purposes.
      Also, TIF_FOREIGN_FPSTATE must always be checked anyway before
      saving FPSIMD context back to memory.  For these reasons, the ->mm
      checks are not useful, providing that TIF_FOREIGN_FPSTATE is
      maintained in a consistent way for all threads.
      
      The context switch logic is already deliberately optimised to defer
      reloads of the regs until ret_to_user (or sigreturn as a special
      case), and save them only if they have been previously loaded.
      These paths are the only places where the wrong_task and wrong_cpu
      conditions can be made false, by calling fpsimd_bind_task_to_cpu().
      Kernel threads by definition never reach these paths.  As a result,
      the wrong_task and wrong_cpu tests in fpsimd_thread_switch() will
      always yield true for kernel threads.
      
      This patch removes the redundant checks and special-case code,
      ensuring that TIF_FOREIGN_FPSTATE is set whenever a kernel thread
      is scheduled in, and ensures that this flag is set for the init
      task.  The fpsimd_flush_task_state() call already present in
      copy_thread() ensures the same for any new task.
      
      With TIF_FOREIGN_FPSTATE always set for kernel threads, this patch
      ensures that no extra context save work is added for kernel
      threads, and eliminates the redundant context saving that may
      currently occur for kernel threads that have acquired an mm via
      use_mm().
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NChristoffer Dall <christoffer.dall@arm.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      df3fb968
    • D
      arm64: fpsimd: Generalise context saving for non-task contexts · d1797615
      Dave Martin 提交于
      In preparation for allowing non-task (i.e., KVM vcpu) FPSIMD
      contexts to be handled by the fpsimd common code, this patch adapts
      task_fpsimd_save() to save back the currently loaded context,
      removing the explicit dependency on current.
      
      The relevant storage to write back to in memory is now found by
      examining the fpsimd_last_state percpu struct.
      
      fpsimd_save() does nothing unless TIF_FOREIGN_FPSTATE is clear, and
      fpsimd_last_state is updated under local_bh_disable() or
      local_irq_disable() everywhere that TIF_FOREIGN_FPSTATE is cleared:
      thus, fpsimd_save() will write back to the correct storage for the
      loaded context.
      
      No functional change.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      d1797615
    • D
      arm64: Use update{,_tsk}_thread_flag() · 09d1223a
      Dave Martin 提交于
      This patch uses the new update_thread_flag() helpers to simplify a
      couple of if () set; else clear; constructs.
      
      No functional change.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      09d1223a
    • D
      arm64: fpsimd: Fix TIF_FOREIGN_FPSTATE after invalidating cpu regs · d8ad71fa
      Dave Martin 提交于
      fpsimd_last_state.st is set to NULL as a way of indicating that
      current's FPSIMD registers are no longer loaded in the cpu.  In
      particular, this is done when the kernel temporarily uses or
      clobbers the FPSIMD registers for its own purposes, as in CPU PM or
      kernel-mode NEON, resulting in them being populated with garbage
      data not belonging to a task.
      
      Commit 17eed27b ("arm64/sve: KVM: Prevent guests from using
      SVE") factors this operation out as a new helper
      fpsimd_flush_cpu_state() to make it clearer what is being done
      here, and on SVE systems this helper is now used, via
      kvm_fpsimd_flush_cpu_state(), to invalidate the registers after KVM
      has run a vcpu.  The reason for this is that KVM does not yet
      understand how to restore the full host SVE registers itself after
      loading the guest FPSIMD context into them.
      
      This exposes a particular problem: if fpsimd_last_state.st is set
      to NULL without also setting TIF_FOREIGN_FPSTATE, the kernel may
      continue to think that current's FPSIMD registers are live even
      though they have actually been clobbered.
      
      Prior to the aforementioned commit, the only path where
      fpsimd_last_state.st is set to NULL without setting
      TIF_FOREIGN_FPSTATE is when kernel_neon_begin() is called by a
      kernel thread (where current->mm can be NULL).  This does not
      matter, because the only harm is that at context-switch time
      fpsimd_thread_switch() may unnecessarily save the FPSIMD registers
      back to current's thread_struct (even though kernel threads are not
      considered to have any FPSIMD context of their own and the
      registers will never be reloaded).
      
      Note that although CPU_PM_ENTER lacks the TIF_FOREIGN_FPSTATE
      setting, every CPU passing through that path must subsequently pass
      through CPU_PM_EXIT before it can re-enter the kernel proper.
      CPU_PM_EXIT sets the flag.
      
      The sve_flush_cpu_state() function added by commit 17eed27b
      also lacks the proper maintenance of TIF_FOREIGN_FPSTATE.  This may
      cause the bits of a host task's SVE registers that do not alias the
      FPSIMD register file to spontaneously appear zeroed if a KVM vcpu
      runs in the same task in the meantime.  Although this effect is
      hidden by the fact that the non-FPSIMD bits of the SVE registers
      are zeroed by a syscall anyway, it is doubtless a bad idea to rely
      on these different code paths interacting correctly under future
      maintenance.
      
      This patch makes TIF_FOREIGN_FPSTATE an unconditional side-effect
      of fpsimd_flush_cpu_state(), and removes the set_thread_flag()
      calls that become redundant as a result.  This ensures that
      TIF_FOREIGN_FPSTATE cannot remain clear if the FPSIMD state in the
      FPSIMD registers is invalid.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NChristoffer Dall <christoffer.dall@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      d8ad71fa
  2. 28 3月, 2018 2 次提交
    • D
      arm64: uaccess: Fix omissions from usercopy whitelist · 65896545
      Dave Martin 提交于
      When the hardend usercopy support was added for arm64, it was
      concluded that all cases of usercopy into and out of thread_struct
      were statically sized and so didn't require explicit whitelisting
      of the appropriate fields in thread_struct.
      
      Testing with usercopy hardening enabled has revealed that this is
      not the case for certain ptrace regset manipulation calls on arm64.
      This occurs because the sizes of usercopies associated with the
      regset API are dynamic by construction, and because arm64 does not
      always stage such copies via the stack: indeed the regset API is
      designed to avoid the need for that by adding some bounds checking.
      
      This is currently believed to affect only the fpsimd and TLS
      registers.
      
      Because the whitelisted fields in thread_struct must be contiguous,
      this patch groups them together in a nested struct.  It is also
      necessary to be able to determine the location and size of that
      struct, so rather than making the struct anonymous (which would
      save on edits elsewhere) or adding an anonymous union containing
      named and unnamed instances of the same struct (gross), this patch
      gives the struct a name and makes the necessary edits to code that
      references it (noisy but simple).
      
      Care is needed to ensure that the new struct does not contain
      padding (which the usercopy hardening would fail to protect).
      
      For this reason, the presence of tp2_value is made unconditional,
      since a padding field would be needed there in any case.  This pads
      up to the 16-byte alignment required by struct user_fpsimd_state.
      Acked-by: NKees Cook <keescook@chromium.org>
      Reported-by: NMark Rutland <mark.rutland@arm.com>
      Fixes: 9e8084d3 ("arm64: Implement thread_struct whitelist for hardened usercopy")
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      65896545
    • D
      arm64: fpsimd: Split cpu field out from struct fpsimd_state · 20b85472
      Dave Martin 提交于
      In preparation for using a common representation of the FPSIMD
      state for tasks and KVM vcpus, this patch separates out the "cpu"
      field that is used to track the cpu on which the state was most
      recently loaded.
      
      This will allow common code to operate on task and vcpu contexts
      without requiring the cpu field to be stored at the same offset
      from the FPSIMD register data in both cases.  This should avoid the
      need for messing with the definition of those parts of struct
      vcpu_arch that are exposed in the KVM user ABI.
      
      The resulting change is also convenient for grouping and defining
      the set of thread_struct fields that are supposed to be accessible
      to copy_{to,from}_user(), which includes user_fpsimd_state but
      should exclude the cpu field.  This patch does not amend the
      usercopy whitelist to match: that will be addressed in a subsequent
      patch.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      [will: inline fpsimd_flush_state for now]
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      20b85472
  3. 27 3月, 2018 1 次提交
    • D
      arm64: capabilities: Update prototype for enable call back · c0cda3b8
      Dave Martin 提交于
      We issue the enable() call back for all CPU hwcaps capabilities
      available on the system, on all the CPUs. So far we have ignored
      the argument passed to the call back, which had a prototype to
      accept a "void *" for use with on_each_cpu() and later with
      stop_machine(). However, with commit 0a0d111d
      ("arm64: cpufeature: Pass capability structure to ->enable callback"),
      there are some users of the argument who wants the matching capability
      struct pointer where there are multiple matching criteria for a single
      capability. Clean up the declaration of the call back to make it clear.
      
       1) Renamed to cpu_enable(), to imply taking necessary actions on the
          called CPU for the entry.
       2) Pass const pointer to the capability, to allow the call back to
          check the entry. (e.,g to check if any action is needed on the CPU)
       3) We don't care about the result of the call back, turning this to
          a void.
      
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Andre Przywara <andre.przywara@arm.com>
      Cc: James Morse <james.morse@arm.com>
      Acked-by: NRobin Murphy <robin.murphy@arm.com>
      Reviewed-by: NJulien Thierry <julien.thierry@arm.com>
      Signed-off-by: NDave Martin <dave.martin@arm.com>
      [suzuki: convert more users, rename call back and drop results]
      Signed-off-by: NSuzuki K Poulose <suzuki.poulose@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      c0cda3b8
  4. 20 3月, 2018 1 次提交
    • D
      arm64: fpsimd: Fix bad si_code for undiagnosed SIGFPE · af4a81b9
      Dave Martin 提交于
      Currently a SIGFPE delivered in response to a floating-point
      exception trap may have si_code set to 0 on arm64.  As reported by
      Eric, this is a bad idea since this is the value of SI_USER -- yet
      this signal is definitely not the result of kill(2), tgkill(2) etc.
      and si_uid and si_pid make limited sense whereas we do want to
      yield a value for si_addr (which doesn't exist for SI_USER).
      
      It's not entirely clear whether the architecure permits a
      "spurious" fp exception trap where none of the exception flag bits
      in ESR_ELx is set.  (IMHO the architectural intent is to forbid
      this.)  However, it does permit those bits to contain garbage if
      the TFV bit in ESR_ELx is 0.  That case isn't currently handled at
      all and may result in si_code == 0 or si_code containing a FPE_FLT*
      constant corresponding to an exception that did not in fact happen.
      
      There is nothing sensible we can return for si_code in such cases,
      but SI_USER is certainly not appropriate and will lead to violation
      of legitimate userspace assumptions.
      
      This patch allocates a new si_code value FPE_UNKNOWN that at least
      does not conflict with any existing SI_* or FPE_* code, and yields
      this in si_code for undiagnosable cases.  This is probably the best
      simplicity/incorrectness tradeoff achieveable without relying on
      implementation-dependent features or adding a lot of code.  In any
      case, there appears to be no perfect solution possible that would
      justify a lot of effort here.
      
      Yielding FPE_UNKNOWN when some well-defined fp exception caused the
      trap is a violation of POSIX, but this is forced by the
      architecture.  We have no realistic prospect of yielding the
      correct code in such cases.  At present I am not aware of any ARMv8
      implementation that supports trapped floating-point exceptions in
      any case.
      
      The new code may be applicable to other architectures for similar
      reasons.
      
      No attempt is made to provide ESR_ELx to userspace in the signal
      frame, since architectural limitations mean that it is unlikely to
      provide much diagnostic value, doesn't benefit existing software
      and would create ABI with no proven purpose.  The existing
      mechanism for passing it also has problems of its own which may
      result in the wrong value being passed to userspace due to
      interaction with mm faults.  The implied rework does not appear
      justified.
      Acked-by: N"Eric W. Biederman" <ebiederm@xmission.com>
      Reported-by: N"Eric W. Biederman" <ebiederm@xmission.com>
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      af4a81b9
  5. 09 3月, 2018 1 次提交
    • D
      arm64: signal: Ensure si_code is valid for all fault signals · af40ff68
      Dave Martin 提交于
      Currently, as reported by Eric, an invalid si_code value 0 is
      passed in many signals delivered to userspace in response to faults
      and other kernel errors.  Typically 0 is passed when the fault is
      insufficiently diagnosable or when there does not appear to be any
      sensible alternative value to choose.
      
      This appears to violate POSIX, and is intuitively wrong for at
      least two reasons arising from the fact that 0 == SI_USER:
      
       1) si_code is a union selector, and SI_USER (and si_code <= 0 in
          general) implies the existence of a different set of fields
          (siginfo._kill) from that which exists for a fault signal
          (siginfo._sigfault).  However, the code raising the signal
          typically writes only the _sigfault fields, and the _kill
          fields make no sense in this case.
      
          Thus when userspace sees si_code == 0 (SI_USER) it may
          legitimately inspect fields in the inactive union member _kill
          and obtain garbage as a result.
      
          There appears to be software in the wild relying on this,
          albeit generally only for printing diagnostic messages.
      
       2) Software that wants to be robust against spurious signals may
          discard signals where si_code == SI_USER (or <= 0), or may
          filter such signals based on the si_uid and si_pid fields of
          siginfo._sigkill.  In the case of fault signals, this means
          that important (and usually fatal) error conditions may be
          silently ignored.
      
      In practice, many of the faults for which arm64 passes si_code == 0
      are undiagnosable conditions such as exceptions with syndrome
      values in ESR_ELx to which the architecture does not yet assign any
      meaning, or conditions indicative of a bug or error in the kernel
      or system and thus that are unrecoverable and should never occur in
      normal operation.
      
      The approach taken in this patch is to translate all such
      undiagnosable or "impossible" synchronous fault conditions to
      SIGKILL, since these are at least probably localisable to a single
      process.  Some of these conditions should really result in a kernel
      panic, but due to the lack of diagnostic information it is
      difficult to be certain: this patch does not add any calls to
      panic(), but this could change later if justified.
      
      Although si_code will not reach userspace in the case of SIGKILL,
      it is still desirable to pass a nonzero value so that the common
      siginfo handling code can detect incorrect use of si_code == 0
      without false positives.  In this case the si_code dependent
      siginfo fields will not be correctly initialised, but since they
      are not passed to userspace I deem this not to matter.
      
      A few faults can reasonably occur in realistic userspace scenarios,
      and _should_ raise a regular, handleable (but perhaps not
      ignorable/blockable) signal: for these, this patch attempts to
      choose a suitable standard si_code value for the raised signal in
      each case instead of 0.
      
      arm64 was the only arch to define a BUS_FIXME code, so after this
      patch nobody defines it.  This patch therefore also removes the
      relevant code from siginfo_layout().
      
      Cc: James Morse <james.morse@arm.com>
      Reported-by: NEric W. Biederman <ebiederm@xmission.com>
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      af40ff68
  6. 07 3月, 2018 1 次提交
    • W
      arm64: signal: Make force_signal_inject more robust · 2c9120f3
      Will Deacon 提交于
      force_signal_inject is a little flakey:
      
        * It only knows about SIGILL and SIGSEGV, so can potentially deliver
          other signals based on a partially initialised siginfo_t
      
        * It sets si_addr to point at the PC for SIGSEGV
      
        * It always operates on current, so doesn't need the regs argument
      
      This patch fixes these issues by always assigning the si_addr field to
      the address parameter of the function and updates the callers (including
      those that indirectly call via arm64_notify_segfault) accordingly.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      2c9120f3
  7. 16 1月, 2018 1 次提交
    • D
      arm64: fpsimd: Fix state leakage when migrating after sigreturn · 0abdeff5
      Dave Martin 提交于
      When refactoring the sigreturn code to handle SVE, I changed the
      sigreturn implementation to store the new FPSIMD state from the
      user sigframe into task_struct before reloading the state into the
      CPU regs.  This makes it easier to convert the data for SVE when
      needed.
      
      However, it turns out that the fpsimd_state structure passed into
      fpsimd_update_current_state is not fully initialised, so assigning
      the structure as a whole corrupts current->thread.fpsimd_state.cpu
      with uninitialised data.
      
      This means that if the garbage data written to .cpu happens to be a
      valid cpu number, and the task is subsequently migrated to the cpu
      identified by the that number, and then tries to enter userspace,
      the CPU FPSIMD regs will be assumed to be correct for the task and
      not reloaded as they should be.  This can result in returning to
      userspace with the FPSIMD registers containing data that is stale or
      that belongs to another task or to the kernel.
      
      Knowingly handing around a kernel structure that is incompletely
      initialised with user data is a potential source of mistakes,
      especially across source file boundaries.  To help avoid a repeat
      of this issue, this patch adapts the relevant internal API to hand
      around the user-accessible subset only: struct user_fpsimd_state.
      
      To avoid future surprises, this patch also converts all uses of
      struct fpsimd_state that really only access the user subset, to use
      struct user_fpsimd_state.  A few missing consts are added to
      function prototypes for good measure.
      
      Thanks to Will for spotting the cause of the bug here.
      Reported-by: NGeert Uytterhoeven <geert@linux-m68k.org>
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      0abdeff5
  8. 13 1月, 2018 1 次提交
    • E
      signal/arm64: Document conflicts with SI_USER and SIGFPE,SIGTRAP,SIGBUS · 526c3ddb
      Eric W. Biederman 提交于
      Setting si_code to 0 results in a userspace seeing an si_code of 0.
      This is the same si_code as SI_USER.  Posix and common sense requires
      that SI_USER not be a signal specific si_code.  As such this use of 0
      for the si_code is a pretty horribly broken ABI.
      
      Further use of si_code == 0 guaranteed that copy_siginfo_to_user saw a
      value of __SI_KILL and now sees a value of SIL_KILL with the result
      that uid and pid fields are copied and which might copying the si_addr
      field by accident but certainly not by design.  Making this a very
      flakey implementation.
      
      Utilizing FPE_FIXME, BUS_FIXME, TRAP_FIXME siginfo_layout will now return
      SIL_FAULT and the appropriate fields will be reliably copied.
      
      But folks this is a new and unique kind of bad.  This is massively
      untested code bad.  This is inventing new and unique was to get
      siginfo wrong bad.  This is don't even think about Posix or what
      siginfo means bad.  This is lots of eyeballs all missing the fact
      that the code does the wrong thing bad.  This is getting stuck
      and keep making the same mistake bad.
      
      I really hope we can find a non userspace breaking fix for this on a
      port as new as arm64.
      
      Possible ABI fixes include:
      - Send the signal without siginfo
      - Don't generate a signal
      - Possibly assign and use an appropriate si_code
      - Don't handle cases which can't happen
      
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Tyler Baicar <tbaicar@codeaurora.org>
      Cc: James Morse <james.morse@arm.com>
      Cc: Tony Lindgren <tony@atomide.com>
      Cc: Nicolas Pitre <nico@linaro.org>
      Cc: Olof Johansson <olof@lixom.net>
      Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
      Cc: Arnd Bergmann <arnd@arndb.de>
      Cc: linux-arm-kernel@lists.infradead.org
      Ref: 53631b54 ("arm64: Floating point and SIMD")
      Ref: 32015c23 ("arm64: exception: handle Synchronous External Abort")
      Ref: 1d18c47c ("arm64: MMU fault handling and page table management")
      Signed-off-by: N"Eric W. Biederman" <ebiederm@xmission.com>
      526c3ddb
  9. 16 12月, 2017 1 次提交
    • W
      arm64: fpsimd: Fix copying of FP state from signal frame into task struct · a4544831
      Will Deacon 提交于
      Commit 9de52a75 ("arm64: fpsimd: Fix failure to restore FPSIMD
      state after signals") fixed an issue reported in our FPSIMD signal
      restore code but inadvertently introduced another issue which tends to
      manifest as random SEGVs in userspace.
      
      The problem is that when we copy the struct fpsimd_state from the kernel
      stack (populated from the signal frame) into the struct held in the
      current thread_struct, we blindly copy uninitialised stack into the
      "cpu" field, which means that context-switching of the FP registers is
      no longer reliable.
      
      This patch fixes the problem by copying only the user_fpsimd member of
      struct fpsimd_state. We should really rework the function prototypes
      to take struct user_fpsimd_state * instead, but let's just get this
      fixed for now.
      
      Cc: Dave Martin <Dave.Martin@arm.com>
      Fixes: 9de52a75 ("arm64: fpsimd: Fix failure to restore FPSIMD state after signals")
      Reported-by: NGeert Uytterhoeven <geert@linux-m68k.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      a4544831
  10. 07 12月, 2017 2 次提交
    • D
      arm64/sve: Avoid dereference of dead task_struct in KVM guest entry · cb968afc
      Dave Martin 提交于
      When deciding whether to invalidate FPSIMD state cached in the cpu,
      the backend function sve_flush_cpu_state() attempts to dereference
      __this_cpu_read(fpsimd_last_state).  However, this is not safe:
      there is no guarantee that this task_struct pointer is still valid,
      because the task could have exited in the meantime.
      
      This means that we need another means to get the appropriate value
      of TIF_SVE for the associated task.
      
      This patch solves this issue by adding a cached copy of the TIF_SVE
      flag in fpsimd_last_state, which we can check without dereferencing
      the task pointer.
      
      In particular, although this patch is not a KVM fix per se, this
      means that this check is now done safely in the KVM world switch
      path (which is currently the only user of this code).
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Christoffer Dall <christoffer.dall@linaro.org>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      cb968afc
    • D
      arm64: fpsimd: Abstract out binding of task's fpsimd context to the cpu. · 8884b7bd
      Dave Martin 提交于
      There is currently some duplicate logic to associate current's
      FPSIMD context with the cpu when loading FPSIMD state into the cpu
      regs.
      
      Subsequent patches will update that logic, so in order to ensure it
      only needs to be done in one place, this patch factors the relevant
      code out into a new function fpsimd_bind_to_cpu().
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      8884b7bd
  11. 01 12月, 2017 1 次提交
    • D
      arm64: fpsimd: Fix failure to restore FPSIMD state after signals · 9de52a75
      Dave Martin 提交于
      The fpsimd_update_current_state() function is responsible for
      loading the FPSIMD state from the user signal frame into the
      current task during sigreturn.  When implementing support for SVE,
      conditional code was added to this function in order to handle the
      case where SVE state need to be loaded for the task and merged with
      the FPSIMD data from the signal frame; however, the FPSIMD-only
      case was unintentionally dropped.
      
      As a result of this, sigreturn does not currently restore the
      FPSIMD state of the task, except in the case where the system
      supports SVE and the signal frame contains SVE state in addition to
      FPSIMD state.
      
      This patch fixes this bug by making the copy-in of the FPSIMD data
      from the signal frame to thread_struct unconditional.
      
      This remains a performance regression from v4.14, since the FPSIMD
      state is now copied into thread_struct and then loaded back,
      instead of _only_ being loaded into the CPU FPSIMD registers.
      However, it is essential to call task_fpsimd_load() here anyway in
      order to ensure that the SVE enable bit in CPACR_EL1 is set
      correctly before returning to userspace.  This could use some
      refactoring, but since sigreturn is not a fast path I have kept
      this patch as a pure fix and left the refactoring for later.
      
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Fixes: 8cd969d2 ("arm64/sve: Signal handling support")
      Reported-by: NAlex Bennée <alex.bennee@linaro.org>
      Tested-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      9de52a75
  12. 03 11月, 2017 13 次提交
    • D
      arm64/sve: KVM: Prevent guests from using SVE · 17eed27b
      Dave Martin 提交于
      Until KVM has full SVE support, guests must not be allowed to
      execute SVE instructions.
      
      This patch enables the necessary traps, and also ensures that the
      traps are disabled again on exit from the guest so that the host
      can still use SVE if it wants to.
      
      On guest exit, high bits of the SVE Zn registers may have been
      clobbered as a side-effect the execution of FPSIMD instructions in
      the guest.  The existing KVM host FPSIMD restore code is not
      sufficient to restore these bits, so this patch explicitly marks
      the CPU as not containing cached vector state for any task, thus
      forcing a reload on the next return to userspace.  This is an
      interim measure, in advance of adding full SVE awareness to KVM.
      
      This marking of cached vector state in the CPU as invalid is done
      using __this_cpu_write(fpsimd_last_state, NULL) in fpsimd.c.  Due
      to the repeated use of this rather obscure operation, it makes
      sense to factor it out as a separate helper with a clearer name.
      This patch factors it out as fpsimd_flush_cpu_state(), and ports
      all callers to use it.
      
      As a side effect of this refactoring, a this_cpu_write() in
      fpsimd_cpu_pm_notifier() is changed to __this_cpu_write().  This
      should be fine, since cpu_pm_enter() is supposed to be called only
      with interrupts disabled.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NChristoffer Dall <christoffer.dall@linaro.org>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      17eed27b
    • D
      arm64/sve: Add sysctl to set the default vector length for new processes · 4ffa09a9
      Dave Martin 提交于
      Because of the effect of SVE on the size of the signal frame, the
      default vector length used for new processes involves a tradeoff
      between performance of SVE-enabled software on the one hand, and
      reliability of non-SVE-aware software on the other hand.
      
      For this reason, the best choice depends on the repertoire of
      userspace software in use and is thus best left up to distro
      maintainers, sysadmins and developers.
      
      If CONFIG_SYSCTL and CONFIG_PROC_SYSCTL are enabled, this patch
      exposes the default vector length in
      /proc/sys/abi/sve_default_vector_length, where boot scripts or the
      adventurous can poke it.
      
      In common with other arm64 ABI sysctls, this control is currently
      global: setting it requires CAP_SYS_ADMIN in the root user
      namespace, but the value set is effective for subsequent execs in
      all namespaces.  The control only affects _new_ processes, however:
      changing it does not affect the vector length of any existing
      process.
      
      The intended usage model is that if userspace is known to be fully
      SVE-tolerant (or a developer is curious to find out) then this
      parameter can be cranked up during system startup.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      4ffa09a9
    • D
      arm64/sve: Add prctl controls for userspace vector length management · 2d2123bc
      Dave Martin 提交于
      This patch adds two arm64-specific prctls, to permit userspace to
      control its vector length:
      
       * PR_SVE_SET_VL: set the thread's SVE vector length and vector
         length inheritance mode.
      
       * PR_SVE_GET_VL: get the same information.
      
      Although these prctls resemble instruction set features in the SVE
      architecture, they provide additional control: the vector length
      inheritance mode is Linux-specific and nothing to do with the
      architecture, and the architecture does not permit EL0 to set its
      own vector length directly.  Both can be used in portable tools
      without requiring the use of SVE instructions.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Alex Bennée <alex.bennee@linaro.org>
      [will: Fixed up prctl constants to avoid clash with PDEATHSIG]
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      2d2123bc
    • D
      arm64/sve: ptrace and ELF coredump support · 43d4da2c
      Dave Martin 提交于
      This patch defines and implements a new regset NT_ARM_SVE, which
      describes a thread's SVE register state.  This allows a debugger to
      manipulate the SVE state, as well as being included in ELF
      coredumps for post-mortem debugging.
      
      Because the regset size and layout are dependent on the thread's
      current vector length, it is not possible to define a C struct to
      describe the regset contents as is done for existing regsets.
      Instead, and for the same reasons, NT_ARM_SVE is based on the
      freeform variable-layout approach used for the SVE signal frame.
      
      Additionally, to reduce debug overhead when debugging threads that
      might or might not have live SVE register state, NT_ARM_SVE may be
      presented in one of two different formats: the old struct
      user_fpsimd_state format is embedded for describing the state of a
      thread with no live SVE state, whereas a new variable-layout
      structure is embedded for describing live SVE state.  This avoids a
      debugger needing to poll NT_PRFPREG in addition to NT_ARM_SVE, and
      allows existing userspace code to handle the non-SVE case without
      too much modification.
      
      For this to work, NT_ARM_SVE is defined with a fixed-format header
      of type struct user_sve_header, which the recipient can use to
      figure out the content, size and layout of the reset of the regset.
      Accessor macros are defined to allow the vector-length-dependent
      parts of the regset to be manipulated.
      Signed-off-by: NAlan Hayward <alan.hayward@arm.com>
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Alex Bennée <alex.bennee@linaro.org>
      Cc: Okamoto Takayuki <tokamoto@jp.fujitsu.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      43d4da2c
    • D
      arm64/sve: Preserve SVE registers around EFI runtime service calls · fdfa976c
      Dave Martin 提交于
      The EFI runtime services ABI allows EFI to make free use of the
      FPSIMD registers during EFI runtime service calls, subject to the
      callee-save requirements of the AArch64 procedure call standard.
      
      However, the SVE architecture allows upper bits of the SVE vector
      registers to be zeroed as a side-effect of FPSIMD V-register
      writes.  This means that the SVE vector registers must be saved in
      their entirety in order to avoid data loss: non-SVE-aware EFI
      implementations cannot restore them correctly.
      
      The non-IRQ case is already handled gracefully by
      kernel_neon_begin().  For the IRQ case, this patch allocates a
      suitable per-CPU stash buffer for the full SVE register state and
      uses it to preserve the affected registers around EFI calls.  It is
      currently unclear how the EFI runtime services ABI will be
      clarified with respect to SVE, so it safest to assume that the
      predicate registers and FFR must be saved and restored too.
      
      No attempt is made to restore the restore the vector length after
      a call, for now.  It is deemed rather insane for EFI to change it,
      and contemporary EFI implementations certainly won't.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      fdfa976c
    • D
      arm64/sve: Preserve SVE registers around kernel-mode NEON use · 1bd3f936
      Dave Martin 提交于
      Kernel-mode NEON will corrupt the SVE vector registers, due to the
      way they alias the FPSIMD vector registers in the hardware.
      
      This patch ensures that any live SVE register content for the task
      is saved by kernel_neon_begin().  The data will be restored in the
      usual way on return to userspace.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      1bd3f936
    • D
      arm64/sve: Probe SVE capabilities and usable vector lengths · 2e0f2478
      Dave Martin 提交于
      This patch uses the cpufeatures framework to determine common SVE
      capabilities and vector lengths, and configures the runtime SVE
      support code appropriately.
      
      ZCR_ELx is not really a feature register, but it is convenient to
      use it as a template for recording the maximum vector length
      supported by a CPU, using the LEN field.  This field is similar to
      a feature field in that it is a contiguous bitfield for which we
      want to determine the minimum system-wide value.  This patch adds
      ZCR as a pseudo-register in cpuinfo/cpufeatures, with appropriate
      custom code to populate it.  Finding the minimum supported value of
      the LEN field is left to the cpufeatures framework in the usual
      way.
      
      The meaning of ID_AA64ZFR0_EL1 is not architecturally defined yet,
      so for now we just require it to be zero.
      
      Note that much of this code is dormant and SVE still won't be used
      yet, since system_supports_sve() remains hardwired to false.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NSuzuki K Poulose <suzuki.poulose@arm.com>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Alex Bennée <alex.bennee@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      2e0f2478
    • D
      arm64/sve: Backend logic for setting the vector length · 7582e220
      Dave Martin 提交于
      This patch implements the core logic for changing a task's vector
      length on request from userspace.  This will be used by the ptrace
      and prctl frontends that are implemented in later patches.
      
      The SVE architecture permits, but does not require, implementations
      to support vector lengths that are not a power of two.  To handle
      this, logic is added to check a requested vector length against a
      possibly sparse bitmap of available vector lengths at runtime, so
      that the best supported value can be chosen.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Alex Bennée <alex.bennee@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      7582e220
    • D
      arm64/sve: Signal handling support · 8cd969d2
      Dave Martin 提交于
      This patch implements support for saving and restoring the SVE
      registers around signals.
      
      A fixed-size header struct sve_context is always included in the
      signal frame encoding the thread's vector length at the time of
      signal delivery, optionally followed by a variable-layout structure
      encoding the SVE registers.
      
      Because of the need to preserve backwards compatibility, the FPSIMD
      view of the SVE registers is always dumped as a struct
      fpsimd_context in the usual way, in addition to any sve_context.
      
      The SVE vector registers are dumped in full, including bits 127:0
      of each register which alias the corresponding FPSIMD vector
      registers in the hardware.  To avoid any ambiguity about which
      alias to restore during sigreturn, the kernel always restores bits
      127:0 of each SVE vector register from the fpsimd_context in the
      signal frame (which must be present): userspace needs to take this
      into account if it wants to modify the SVE vector register contents
      on return from a signal.
      
      FPSR and FPCR, which are used by both FPSIMD and SVE, are not
      included in sve_context because they are always present in
      fpsimd_context anyway.
      
      For signal delivery, a new helper
      fpsimd_signal_preserve_current_state() is added to update _both_
      the FPSIMD and SVE views in the task struct, to make it easier to
      populate this information into the signal frame.  Because of the
      redundancy between the two views of the state, only one is updated
      otherwise.
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Cc: Alex Bennée <alex.bennee@linaro.org>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Will Deacon <will.deacon@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      8cd969d2
    • D
      arm64/sve: Support vector length resetting for new processes · 79ab047c
      Dave Martin 提交于
      It's desirable to be able to reset the vector length to some sane
      default for new processes, since the new binary and its libraries
      may or may not be SVE-aware.
      
      This patch tracks the desired post-exec vector length (if any) in a
      new thread member sve_vl_onexec, and adds a new thread flag
      TIF_SVE_VL_INHERIT to control whether to inherit or reset the
      vector length.  Currently these are inactive.  Subsequent patches
      will provide the capability to configure them.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      79ab047c
    • D
      arm64/sve: Core task context handling · bc0ee476
      Dave Martin 提交于
      This patch adds the core support for switching and managing the SVE
      architectural state of user tasks.
      
      Calls to the existing FPSIMD low-level save/restore functions are
      factored out as new functions task_fpsimd_{save,load}(), since SVE
      now dynamically may or may not need to be handled at these points
      depending on the kernel configuration, hardware features discovered
      at boot, and the runtime state of the task.  To make these
      decisions as fast as possible, const cpucaps are used where
      feasible, via the system_supports_sve() helper.
      
      The SVE registers are only tracked for threads that have explicitly
      used SVE, indicated by the new thread flag TIF_SVE.  Otherwise, the
      FPSIMD view of the architectural state is stored in
      thread.fpsimd_state as usual.
      
      When in use, the SVE registers are not stored directly in
      thread_struct due to their potentially large and variable size.
      Because the task_struct slab allocator must be configured very
      early during kernel boot, it is also tricky to configure it
      correctly to match the maximum vector length provided by the
      hardware, since this depends on examining secondary CPUs as well as
      the primary.  Instead, a pointer sve_state in thread_struct points
      to a dynamically allocated buffer containing the SVE register data,
      and code is added to allocate and free this buffer at appropriate
      times.
      
      TIF_SVE is set when taking an SVE access trap from userspace, if
      suitable hardware support has been detected.  This enables SVE for
      the thread: a subsequent return to userspace will disable the trap
      accordingly.  If such a trap is taken without sufficient system-
      wide hardware support, SIGILL is sent to the thread instead as if
      an undefined instruction had been executed: this may happen if
      userspace tries to use SVE in a system where not all CPUs support
      it for example.
      
      The kernel will clear TIF_SVE and disable SVE for the thread
      whenever an explicit syscall is made by userspace.  For backwards
      compatibility reasons and conformance with the spirit of the base
      AArch64 procedure call standard, the subset of the SVE register
      state that aliases the FPSIMD registers is still preserved across a
      syscall even if this happens.  The remainder of the SVE register
      state logically becomes zero at syscall entry, though the actual
      zeroing work is currently deferred until the thread next tries to
      use SVE, causing another trap to the kernel.  This implementation
      is suboptimal: in the future, the fastpath case may be optimised
      to zero the registers in-place and leave SVE enabled for the task,
      where beneficial.
      
      TIF_SVE is also cleared in the following slowpath cases, which are
      taken as reasonable hints that the task may no longer use SVE:
       * exec
       * fork and clone
      
      Code is added to sync data between thread.fpsimd_state and
      thread.sve_state whenever enabling/disabling SVE, in a manner
      consistent with the SVE architectural programmer's model.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Cc: Alex Bennée <alex.bennee@linaro.org>
      [will: added #include to fix allnoconfig build]
      [will: use enable_daif in do_sve_acc]
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      bc0ee476
    • D
      arm64: fpsimd: Simplify uses of {set,clear}_ti_thread_flag() · 9cf5b54f
      Dave Martin 提交于
      The existing FPSIMD context switch code contains a couple of
      instances of {set,clear}_ti_thread(task_thread_info(task)).  Since
      there are thread flag manipulators that operate directly on
      task_struct, this verbosity isn't strictly needed.
      
      For consistency, this patch simplifies the affected calls.  This
      should have no impact on behaviour.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Acked-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      9cf5b54f
    • D
      arm64: fpsimd: Correctly annotate exception helpers called from asm · 94ef7ecb
      Dave Martin 提交于
      A couple of FPSIMD exception handling functions that are called
      from entry.S are currently not annotated as such.
      
      This is not a big deal since asmlinkage does nothing on arm/arm64,
      but fixing the annotations is more consistent and may help avoid
      future surprises.
      
      This patch adds appropriate asmlinkage annotations for
      do_fpsimd_acc() and do_fpsimd_exc().
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      94ef7ecb
  13. 06 10月, 2017 1 次提交
  14. 18 9月, 2017 1 次提交
  15. 23 8月, 2017 1 次提交
    • D
      arm64: fpsimd: Prevent registers leaking across exec · 09662210
      Dave Martin 提交于
      There are some tricky dependencies between the different stages of
      flushing the FPSIMD register state during exec, and these can race
      with context switch in ways that can cause the old task's regs to
      leak across.  In particular, a context switch during the memset() can
      cause some of the task's old FPSIMD registers to reappear.
      
      Disabling preemption for this small window would be no big deal for
      performance: preemption is already disabled for similar scenarios
      like updating the FPSIMD registers in sigreturn.
      
      So, instead of rearranging things in ways that might swap existing
      subtle bugs for new ones, this patch just disables preemption
      around the FPSIMD state flushing so that races of this type can't
      occur here.  This brings fpsimd_flush_thread() into line with other
      code paths.
      
      Cc: stable@vger.kernel.org
      Fixes: 674c242c ("arm64: flush FP/SIMD state correctly after execve()")
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      09662210
  16. 19 8月, 2017 1 次提交
  17. 07 8月, 2017 1 次提交
  18. 04 8月, 2017 2 次提交
    • D
      arm64: neon: Remove support for nested or hardirq kernel-mode NEON · cb84d11e
      Dave Martin 提交于
      Support for kernel-mode NEON to be nested and/or used in hardirq
      context adds significant complexity, and the benefits may be
      marginal.  In practice, kernel-mode NEON is not used in hardirq
      context, and is rarely used in softirq context (by certain mac80211
      drivers).
      
      This patch implements an arm64 may_use_simd() function to allow
      clients to check whether kernel-mode NEON is usable in the current
      context, and simplifies kernel_neon_{begin,end}() to handle only
      saving of the task FPSIMD state (if any).  Without nesting, there
      is no other state to save.
      
      The partial fpsimd save/restore functions become redundant as a
      result of these changes, so they are removed too.
      
      The save/restore model is changed to operate directly on
      task_struct without additional percpu storage.  This simplifies the
      code and saves a bit of memory, but means that softirqs must now be
      disabled when manipulating the task fpsimd state from task context:
      correspondingly, preempt_{en,dis}sable() calls are upgraded to
      local_bh_{en,dis}able() as appropriate.  fpsimd_thread_switch()
      already runs with hardirqs disabled and so is already protected
      from softirqs.
      
      These changes should make it easier to support kernel-mode NEON in
      the presence of the Scalable Vector extension in the future.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      cb84d11e
    • D
      arm64: neon: Allow EFI runtime services to use FPSIMD in irq context · 4328825d
      Dave Martin 提交于
      In order to be able to cope with kernel-mode NEON being unavailable
      in hardirq/nmi context and non-nestable, we need special handling
      for EFI runtime service calls that may be made during an interrupt
      that interrupted a kernel_neon_begin()..._end() block.  This will
      occur if the kernel tries to write diagnostic data to EFI
      persistent storage during a panic triggered by an NMI for example.
      
      EFI runtime services specify an ABI that clobbers the FPSIMD state,
      rather than being able to use it optionally as an accelerator.
      This means that EFI is really a special case and can be handled
      specially.
      
      To enable EFI calls from interrupts, this patch creates dedicated
      __efi_fpsimd_{begin,end}() helpers solely for this purpose, which
      save/restore to a separate percpu buffer if called in a context
      where kernel_neon_begin() is not usable.
      Signed-off-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      4328825d