All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
Subject: Re: [PATCH 5.15 v2 03/10] arm64/fpsimd: Track the saved FPSIMD state type separately to TIF_SVE
Date: Thu,  3 Apr 2025 11:38:35 -0400	[thread overview]
Message-ID: <20250403095427-6690dadd0b0b61dc@stable.kernel.org> (raw)
In-Reply-To: <20250403-stable-sve-5-15-v2-3-30a36a78a20a@kernel.org>

[ Sasha's backport helper bot ]

Hi,

✅ All tests passed successfully. No issues detected.
No action required from the submitter.

The upstream commit SHA1 provided is correct: baa8515281b30861cff3da7db70662d2a25c6440

Status in newer kernel trees:
6.13.y | Present (exact SHA1)
6.12.y | Present (exact SHA1)
6.6.y | Present (exact SHA1)
6.1.y | Not found

Note: The patch differs from the upstream commit:
---
1:  baa8515281b30 ! 1:  e5d18d62553b8 arm64/fpsimd: Track the saved FPSIMD state type separately to TIF_SVE
    @@ Metadata
      ## Commit message ##
         arm64/fpsimd: Track the saved FPSIMD state type separately to TIF_SVE
     
    +    [ Upstream commit baa8515281b30861cff3da7db70662d2a25c6440 ]
    +
         When we save the state for the floating point registers this can be done
         in the form visible through either the FPSIMD V registers or the SVE Z and
         P registers. At present we track which format is currently used based on
    @@ Commit message
         Reviewed-by: Marc Zyngier <maz@kernel.org>
         Link: https://lore.kernel.org/r/20221115094640.112848-3-broonie@kernel.org
         Signed-off-by: Will Deacon <will@kernel.org>
    +    [ Mark: fix conflicts due to earlier backports ]
    +    Signed-off-by: Mark Rutland <mark.rutland@arm.com>
    +    Signed-off-by: Mark Brown <broonie@kernel.org>
     
      ## arch/arm64/include/asm/fpsimd.h ##
    -@@ arch/arm64/include/asm/fpsimd.h: extern void fpsimd_kvm_prepare(void);
    +@@ arch/arm64/include/asm/fpsimd.h: extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
    + extern void fpsimd_kvm_prepare(void);
    + 
      extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
    - 				     void *sve_state, unsigned int sve_vl,
    - 				     void *za_state, unsigned int sme_vl,
    --				     u64 *svcr);
    -+				     u64 *svcr, enum fp_type *type);
    +-				     void *sve_state, unsigned int sve_vl);
    ++				     void *sve_state, unsigned int sve_vl,
    ++				     enum fp_type *type);
      
      extern void fpsimd_flush_task_state(struct task_struct *target);
      extern void fpsimd_save_and_flush_cpu_state(void);
     
      ## arch/arm64/include/asm/kvm_host.h ##
     @@ arch/arm64/include/asm/kvm_host.h: struct vcpu_reset_state {
    + 
      struct kvm_vcpu_arch {
      	struct kvm_cpu_context ctxt;
    - 
    --	/* Guest floating point state */
    ++
     +	/*
     +	 * Guest floating point state
     +	 *
    @@ arch/arm64/include/asm/kvm_host.h: struct vcpu_reset_state {
      	void *sve_state;
     +	enum fp_type fp_type;
      	unsigned int sve_max_vl;
    - 	u64 svcr;
      
    + 	/* Stage 2 paging state used by the hardware on next switch */
     
      ## arch/arm64/include/asm/processor.h ##
    -@@ arch/arm64/include/asm/processor.h: enum vec_type {
    - 	ARM64_VEC_MAX,
    +@@ arch/arm64/include/asm/processor.h: struct debug_info {
    + #endif
      };
      
     +enum fp_type {
    @@ arch/arm64/include/asm/processor.h: struct thread_struct {
     +	enum fp_type		fp_type;	/* registers FPSIMD or SVE? */
      	unsigned int		fpsimd_cpu;
      	void			*sve_state;	/* SVE registers, if any */
    - 	void			*za_state;	/* ZA register, if any */
    + 	unsigned int		sve_vl;		/* SVE vector length */
     
      ## arch/arm64/kernel/fpsimd.c ##
     @@ arch/arm64/kernel/fpsimd.c: struct fpsimd_last_state_struct {
    - 	u64 *svcr;
    + 	struct user_fpsimd_state *st;
    + 	void *sve_state;
      	unsigned int sve_vl;
    - 	unsigned int sme_vl;
     +	enum fp_type *fp_type;
      };
      
      static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state);
    -@@ arch/arm64/kernel/fpsimd.c: void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
    +@@ arch/arm64/kernel/fpsimd.c: static void sve_free(struct task_struct *task)
       *    The task can execute SVE instructions while in userspace without
       *    trapping to the kernel.
       *
     - *    When stored, Z0-Z31 (incorporating Vn in bits[127:0] or the
    -- *    corresponding Zn), P0-P15 and FFR are encoded in
    +- *    corresponding Zn), P0-P15 and FFR are encoded in in
     - *    task->thread.sve_state, formatted appropriately for vector
    -- *    length task->thread.sve_vl or, if SVCR.SM is set,
    -- *    task->thread.sme_vl.
    +- *    length task->thread.sve_vl.
     - *
     - *    task->thread.sve_state must point to a valid buffer at least
     - *    sve_state_size(task) bytes in size.
    @@ arch/arm64/kernel/fpsimd.c: void task_set_vl_onexec(struct task_struct *task, en
       *    During any syscall, the kernel may optionally clear TIF_SVE and
       *    discard the vector state except for the FPSIMD subset.
       *
    -@@ arch/arm64/kernel/fpsimd.c: void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
    +@@ arch/arm64/kernel/fpsimd.c: static void sve_free(struct task_struct *task)
       *    do_sve_acc() to be called, which does some preparation and then
       *    sets TIF_SVE.
       *
    @@ arch/arm64/kernel/fpsimd.c: void task_set_vl_onexec(struct task_struct *task, en
       *    task->thread.uw.fpsimd_state; bits [max : 128] for each of Z0-Z31 are
       *    logically zero but not stored anywhere; P0-P15 and FFR are not
       *    stored and have unspecified values from userspace's point of
    -@@ arch/arm64/kernel/fpsimd.c: void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
    +@@ arch/arm64/kernel/fpsimd.c: static void sve_free(struct task_struct *task)
       *    task->thread.sve_state does not need to be non-NULL, valid or any
       *    particular size: it must not be dereferenced.
       *
    @@ arch/arm64/kernel/fpsimd.c: void task_set_vl_onexec(struct task_struct *task, en
       *    irrespective of whether TIF_SVE is clear or set, since these are
       *    not vector length dependent.
     @@ arch/arm64/kernel/fpsimd.c: static void task_fpsimd_load(void)
    - 		}
    - 	}
    + 	WARN_ON(!system_supports_fpsimd());
    + 	WARN_ON(!have_cpu_fpsimd_context());
      
    --	if (restore_sve_regs)
    -+	if (restore_sve_regs) {
    +-	if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE))
    ++	if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) {
     +		WARN_ON_ONCE(current->thread.fp_type != FP_STATE_SVE);
      		sve_load_state(sve_pffr(&current->thread),
      			       &current->thread.uw.fpsimd_state.fpsr,
    - 			       restore_ffr);
    + 			       sve_vq_from_vl(current->thread.sve_vl) - 1);
     -	else
     +	} else {
     +		WARN_ON_ONCE(current->thread.fp_type != FP_STATE_FPSIMD);
    @@ arch/arm64/kernel/fpsimd.c: static void task_fpsimd_load(void)
      
      /*
     @@ arch/arm64/kernel/fpsimd.c: static void fpsimd_save(void)
    - 		sve_save_state((char *)last->sve_state +
    - 					sve_ffr_offset(vl),
    - 			       &last->st->fpsr, save_ffr);
    -+		*last->fp_type = FP_STATE_SVE;
    - 	} else {
    - 		fpsimd_save_state(last->st);
    -+		*last->fp_type = FP_STATE_FPSIMD;
    + 			sve_save_state((char *)last->sve_state +
    + 						sve_ffr_offset(last->sve_vl),
    + 				       &last->st->fpsr);
    +-		} else
    ++			*last->fp_type = FP_STATE_SVE;
    ++		} else {
    + 			fpsimd_save_state(last->st);
    ++			*last->fp_type = FP_STATE_FPSIMD;
    ++		}
      	}
      }
      
    -@@ arch/arm64/kernel/fpsimd.c: int vec_set_vector_length(struct task_struct *task, enum vec_type type,
    +@@ arch/arm64/kernel/fpsimd.c: int sve_set_vector_length(struct task_struct *task,
    + 	}
      
      	fpsimd_flush_task_state(task);
    - 	if (test_and_clear_tsk_thread_flag(task, TIF_SVE) ||
    --	    thread_sm_enabled(&task->thread))
    -+	    thread_sm_enabled(&task->thread)) {
    +-	if (test_and_clear_tsk_thread_flag(task, TIF_SVE))
    ++	if (test_and_clear_tsk_thread_flag(task, TIF_SVE)) {
      		sve_to_fpsimd(task);
     +		task->thread.fp_type = FP_STATE_FPSIMD;
     +	}
      
    - 	if (system_supports_sme() && type == ARM64_VEC_SME) {
    - 		task->thread.svcr &= ~(SVCR_SM_MASK |
    -@@ arch/arm64/kernel/fpsimd.c: static void sve_init_regs(void)
    - 		fpsimd_bind_task_to_cpu();
    - 	} else {
    - 		fpsimd_to_sve(current);
    -+		current->thread.fp_type = FP_STATE_SVE;
    - 	}
    - }
    - 
    + 	if (task == current)
    + 		put_cpu_fpsimd_context();
     @@ arch/arm64/kernel/fpsimd.c: void fpsimd_flush_thread(void)
    - 		current->thread.svcr = 0;
    + 			current->thread.sve_vl_onexec = 0;
      	}
      
     +	current->thread.fp_type = FP_STATE_FPSIMD;
     +
      	put_cpu_fpsimd_context();
    - 	kfree(sve_state);
    - 	kfree(za_state);
    + }
    + 
     @@ arch/arm64/kernel/fpsimd.c: void fpsimd_kvm_prepare(void)
      	 */
      	get_cpu_fpsimd_context();
    @@ arch/arm64/kernel/fpsimd.c: void fpsimd_kvm_prepare(void)
      	put_cpu_fpsimd_context();
      }
     @@ arch/arm64/kernel/fpsimd.c: static void fpsimd_bind_task_to_cpu(void)
    - 	last->sve_vl = task_get_sve_vl(current);
    - 	last->sme_vl = task_get_sme_vl(current);
    - 	last->svcr = &current->thread.svcr;
    + 	last->st = &current->thread.uw.fpsimd_state;
    + 	last->sve_state = current->thread.sve_state;
    + 	last->sve_vl = current->thread.sve_vl;
     +	last->fp_type = &current->thread.fp_type;
      	current->thread.fpsimd_cpu = smp_processor_id();
      
    - 	/*
    + 	if (system_supports_sve()) {
     @@ arch/arm64/kernel/fpsimd.c: static void fpsimd_bind_task_to_cpu(void)
    + }
      
      void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
    - 			      unsigned int sve_vl, void *za_state,
    --			      unsigned int sme_vl, u64 *svcr)
    -+			      unsigned int sme_vl, u64 *svcr,
    -+			      enum fp_type *type)
    +-			      unsigned int sve_vl)
    ++			      unsigned int sve_vl, enum fp_type *type)
      {
      	struct fpsimd_last_state_struct *last =
      		this_cpu_ptr(&fpsimd_last_state);
     @@ arch/arm64/kernel/fpsimd.c: void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
    - 	last->za_state = za_state;
    + 	last->st = st;
    + 	last->sve_state = sve_state;
      	last->sve_vl = sve_vl;
    - 	last->sme_vl = sme_vl;
     +	last->fp_type = type;
      }
      
    @@ arch/arm64/kernel/fpsimd.c: void fpsimd_bind_state_to_cpu(struct user_fpsimd_sta
     
      ## arch/arm64/kernel/process.c ##
     @@ arch/arm64/kernel/process.c: int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
    - 		clear_tsk_thread_flag(dst, TIF_SME);
    - 	}
    + 	dst->thread.sve_state = NULL;
    + 	clear_tsk_thread_flag(dst, TIF_SVE);
      
    ++
     +	dst->thread.fp_type = FP_STATE_FPSIMD;
     +
      	/* clear any pending asynchronous tag fault raised by the parent */
    @@ arch/arm64/kernel/process.c: int arch_dup_task_struct(struct task_struct *dst, s
      
     
      ## arch/arm64/kernel/ptrace.c ##
    -@@ arch/arm64/kernel/ptrace.c: static int sve_set_common(struct task_struct *target,
    +@@ arch/arm64/kernel/ptrace.c: static int sve_set(struct task_struct *target,
    + 		ret = __fpr_set(target, regset, pos, count, kbuf, ubuf,
    + 				SVE_PT_FPSIMD_OFFSET);
      		clear_tsk_thread_flag(target, TIF_SVE);
    - 		if (type == ARM64_VEC_SME)
    - 			fpsimd_force_sync_to_sve(target);
     +		target->thread.fp_type = FP_STATE_FPSIMD;
      		goto out;
      	}
      
    -@@ arch/arm64/kernel/ptrace.c: static int sve_set_common(struct task_struct *target,
    +@@ arch/arm64/kernel/ptrace.c: static int sve_set(struct task_struct *target,
      	if (!target->thread.sve_state) {
      		ret = -ENOMEM;
      		clear_tsk_thread_flag(target, TIF_SVE);
    @@ arch/arm64/kernel/ptrace.c: static int sve_set_common(struct task_struct *target
      		goto out;
      	}
      
    -@@ arch/arm64/kernel/ptrace.c: static int sve_set_common(struct task_struct *target,
    +@@ arch/arm64/kernel/ptrace.c: static int sve_set(struct task_struct *target,
      	 */
      	fpsimd_sync_to_sve(target);
      	set_tsk_thread_flag(target, TIF_SVE);
    @@ arch/arm64/kernel/signal.c: static int restore_fpsimd_context(struct fpsimd_cont
      	/* load the hardware registers from the fpsimd_state structure */
      	if (!err)
     @@ arch/arm64/kernel/signal.c: static int restore_sve_fpsimd_context(struct user_ctxs *user)
    + 
      	if (sve.head.size <= sizeof(*user->sve)) {
      		clear_thread_flag(TIF_SVE);
    - 		current->thread.svcr &= ~SVCR_SM_MASK;
     +		current->thread.fp_type = FP_STATE_FPSIMD;
      		goto fpsimd_only;
      	}
      
     @@ arch/arm64/kernel/signal.c: static int restore_sve_fpsimd_context(struct user_ctxs *user)
    - 		current->thread.svcr |= SVCR_SM_MASK;
    - 	else
    - 		set_thread_flag(TIF_SVE);
    + 		return -EFAULT;
    + 
    + 	set_thread_flag(TIF_SVE);
     +	current->thread.fp_type = FP_STATE_SVE;
      
      fpsimd_only:
      	/* copy the FP and status/control registers */
    -@@ arch/arm64/kernel/signal.c: static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
    - 		 * FPSIMD register state - flush the saved FPSIMD
    - 		 * register state in case it gets loaded.
    - 		 */
    --		if (current->thread.svcr & SVCR_SM_MASK)
    -+		if (current->thread.svcr & SVCR_SM_MASK) {
    - 			memset(&current->thread.uw.fpsimd_state, 0,
    - 			       sizeof(current->thread.uw.fpsimd_state));
    -+			current->thread.fp_type = FP_STATE_FPSIMD;
    -+		}
    - 
    - 		current->thread.svcr &= ~(SVCR_ZA_MASK |
    - 					  SVCR_SM_MASK);
     
      ## arch/arm64/kvm/fpsimd.c ##
     @@ arch/arm64/kvm/fpsimd.c: void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
    + 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
      		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
      					 vcpu->arch.sve_state,
    - 					 vcpu->arch.sve_max_vl,
    --					 NULL, 0, &vcpu->arch.svcr);
    -+					 NULL, 0, &vcpu->arch.svcr,
    +-					 vcpu->arch.sve_max_vl);
    ++					 vcpu->arch.sve_max_vl,
     +					 &vcpu->arch.fp_type);
      
      		clear_thread_flag(TIF_FOREIGN_FPSTATE);
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.1.y        |  Success    |  Success   |

  reply	other threads:[~2025-04-03 15:38 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-02 23:20 [PATCH 5.15 v2 00/10] KVM: arm64: Backport of SVE fixes to v5.15 Mark Brown
2025-04-02 23:20 ` [PATCH 5.15 v2 01/10] KVM: arm64: Get rid of host SVE tracking/saving Mark Brown
2025-04-03 15:38   ` Sasha Levin
2025-04-03 16:04     ` Mark Brown
2025-04-03 16:10     ` Mark Brown
2025-04-02 23:20 ` [PATCH 5.15 v2 02/10] KVM: arm64: Discard any SVE state when entering KVM guests Mark Brown
2025-04-03 15:39   ` Sasha Levin
2025-04-03 16:27     ` Mark Brown
2025-04-02 23:20 ` [PATCH 5.15 v2 03/10] arm64/fpsimd: Track the saved FPSIMD state type separately to TIF_SVE Mark Brown
2025-04-03 15:38   ` Sasha Levin [this message]
2025-04-02 23:20 ` [PATCH 5.15 v2 04/10] arm64/fpsimd: Have KVM explicitly say which FP registers to save Mark Brown
2025-04-03 15:39   ` Sasha Levin
2025-04-02 23:20 ` [PATCH 5.15 v2 05/10] arm64/fpsimd: Stop using TIF_SVE to manage register saving in KVM Mark Brown
2025-04-03 15:38   ` Sasha Levin
2025-04-02 23:20 ` [PATCH 5.15 v2 06/10] KVM: arm64: Unconditionally save+flush host FPSIMD/SVE/SME state Mark Brown
2025-04-03 15:39   ` Sasha Levin
2025-04-02 23:20 ` [PATCH 5.15 v2 07/10] KVM: arm64: Remove host FPSIMD saving for non-protected KVM Mark Brown
2025-04-03 15:39   ` Sasha Levin
2025-04-02 23:20 ` [PATCH 5.15 v2 08/10] KVM: arm64: Remove VHE host restore of CPACR_EL1.ZEN Mark Brown
2025-04-03 15:38   ` Sasha Levin
2025-04-02 23:20 ` [PATCH 5.15 v2 09/10] KVM: arm64: Calculate cptr_el2 traps on activating traps Mark Brown
2025-04-03 15:38   ` Sasha Levin
2025-04-02 23:20 ` [PATCH 5.15 v2 10/10] KVM: arm64: Eagerly switch ZCR_EL{1,2} Mark Brown
2025-04-03 15:39   ` Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250403095427-6690dadd0b0b61dc@stable.kernel.org \
    --to=sashal@kernel.org \
    --cc=broonie@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.