# FPU, SIMD, SVE/SME, XSAVE와 RISC-V Vector state

v6.18.37 / arch/x86/include/asm/fpu/sched.h

정수 레지스터를 바꿔도 SIMD와 벡터 레지스터에 이전 task의 계산값이 남을 수 있습니다. arm64는 FPSIMD·SVE·SME, x86은 FPU/XSAVE 상태, RISC-V는 FP 및 Vector 상태를 별도로 관리합니다. 대표로 x86 switch_fpu에서 언제 저장이 필요한지 읽습니다.

## switch_fpu

```c

static inline void switch_fpu(struct task_struct *old, int cpu)
{
	if (!test_tsk_thread_flag(old, TIF_NEED_FPU_LOAD) &&
	    cpu_feature_enabled(X86_FEATURE_FPU) &&
	    !(old->flags & (PF_KTHREAD | PF_USER_WORKER))) {
		struct fpu *old_fpu = x86_task_fpu(old);

		set_tsk_thread_flag(old, TIF_NEED_FPU_LOAD);
		save_fpregs_to_fpstate(old_fpu);
		/*
		 * The save operation preserved register state, so the
		 * fpu_fpregs_owner_ctx is still @old_fpu. Store the
		 * current CPU number in @old_fpu, so the next return
		 * to user space can avoid the FPU register restore
		 * when is returns on the same CPU and still owns the
		 * context. See fpregs_restore_userregs().
		 */
		old_fpu->last_cpu = cpu;

		trace_x86_fpu_regs_deactivated(old_fpu);
	}
}

```

### 32행

```c

static inline void switch_fpu(struct task_struct *old, int cpu)

```

이전 task와 현재 CPU 번호를 받아 전환 시 FP 저장이 필요한지 판단합니다. 이 함수는 다음 task의 상태를 무조건 즉시 복원하는 함수가 아닙니다.

### 34행

```c

	if (!test_tsk_thread_flag(old, TIF_NEED_FPU_LOAD) &&

```

이전 task에 이미 NEED_FPU_LOAD가 설정되어 있다면 현재 레지스터를 그 task의 최신 값으로 가정할 수 없습니다. 플래그가 없는 경우만 다음 조건을 확인합니다.

### 35행

```c

	    cpu_feature_enabled(X86_FEATURE_FPU) &&

```

실제 FPU 지원이 있는지도 검사합니다. 소프트웨어 상태만 보고 없는 하드웨어에 접근하지 않게 합니다.

### 36행

```c

	    !(old->flags & (PF_KTHREAD | PF_USER_WORKER))) {

```

일반 사용자 FP 문맥 대상이 아닌 커널 스레드와 사용자 worker를 제외합니다. 세 조건이 모두 맞을 때 본문으로 들어갑니다.

### 37행

```c

		struct fpu *old_fpu = x86_task_fpu(old);

```

이전 task의 FP 저장 자료구조를 얻습니다. CPU 레지스터의 값을 보관할 메모리 쪽 대상입니다.

### 39행

```c

		set_tsk_thread_flag(old, TIF_NEED_FPU_LOAD);

```

이 task를 다음에 사용할 때 FP load 여부를 다시 판단해야 함을 표시합니다.

### 40행

```c

		save_fpregs_to_fpstate(old_fpu);

```

실제 FP 레지스터 내용을 해당 task의 메모리 저장 상태로 보존합니다.

### 49행

```c

		old_fpu->last_cpu = cpu;

```

저장 후에도 CPU 레지스터 내용이 보존되므로 마지막 CPU 번호를 기억합니다. 같은 CPU에서 소유권이 유지되면 이후 불필요한 복원을 피할 근거가 됩니다.

### 51행

```c

		trace_x86_fpu_regs_deactivated(old_fpu);

```

FP 레지스터 소유가 비활성화된 사건을 추적에 남깁니다. 상태를 추가로 복원하는 명령은 아닙니다.

