arch/arm64/kvm/fpsimd.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/fpsimd.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/fpsimd.c- Extension
.c- Size
- 4613 bytes
- Lines
- 149
- Domain
- Architecture Layer
- Bucket
- arch/arm64
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/irqflags.hlinux/sched.hlinux/kvm_host.hasm/fpsimd.hasm/kvm_asm.hasm/kvm_hyp.hasm/kvm_mmu.hasm/sysreg.h
Detected Declarations
function regsfunction vcpu_get_flagfunction preemptiblefunction kvm_arch_vcpu_ctxsync_fpfunction kvm_arch_vcpu_put_fpfunction kvm_arch_vcpu_load_fp
Annotated Snippet
vcpu_get_flag(vcpu, IN_NESTED_EXCEPTION)) {
WARN_ON_ONCE(host_owns_fp_regs());
return;
}
/*
* Ensure that any host FPSIMD/SVE/SME state is saved and unbound such
* that the host kernel is responsible for restoring this state upon
* return to userspace, and the hyp code doesn't need to save anything.
*
* When the host may use SME, fpsimd_save_and_flush_cpu_state() ensures
* that PSTATE.{SM,ZA} == {0,0}.
*/
fpsimd_save_and_flush_cpu_state();
*host_data_ptr(fp_owner) = FP_STATE_FREE;
WARN_ON_ONCE(system_supports_sme() && read_sysreg_s(SYS_SVCR));
}
/*
* Called just before entering the guest once we are no longer preemptible
* and interrupts are disabled. If we have managed to run anything using
* FP while we were preemptible (such as off the back of an interrupt),
* then neither the host nor the guest own the FP hardware (and it was the
* responsibility of the code that used FP to save the existing state).
*/
void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
{
if (test_thread_flag(TIF_FOREIGN_FPSTATE))
*host_data_ptr(fp_owner) = FP_STATE_FREE;
}
/*
* Called just after exiting the guest. If the guest FPSIMD state
* was loaded, update the host's context tracking data mark the CPU
* FPSIMD regs as dirty and belonging to vcpu so that they will be
* written back if the kernel clobbers them due to kernel-mode NEON
* before re-entry into the guest.
*/
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
{
struct cpu_fp_state fp_state;
WARN_ON_ONCE(!irqs_disabled());
if (guest_owns_fp_regs()) {
/*
* Currently we do not support SME guests so SVCR is
* always 0 and we just need a variable to point to.
*/
fp_state.st = &vcpu->arch.ctxt.fp_regs;
fp_state.sve_state = vcpu->arch.sve_state;
fp_state.sve_vl = vcpu->arch.sve_max_vl;
fp_state.sme_state = NULL;
fp_state.svcr = __ctxt_sys_reg(&vcpu->arch.ctxt, SVCR);
fp_state.fpmr = __ctxt_sys_reg(&vcpu->arch.ctxt, FPMR);
fp_state.fp_type = &vcpu->arch.fp_type;
if (vcpu_has_sve(vcpu))
fp_state.to_save = FP_STATE_SVE;
else
fp_state.to_save = FP_STATE_FPSIMD;
fpsimd_bind_state_to_cpu(&fp_state);
clear_thread_flag(TIF_FOREIGN_FPSTATE);
}
}
/*
* Write back the vcpu FPSIMD regs if they are dirty, and invalidate the
* cpu FPSIMD regs so that they can't be spuriously reused if this vcpu
* disappears and another task or vcpu appears that recycles the same
* struct fpsimd_state.
*/
void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
{
unsigned long flags;
/*
* See comment in kvm_arch_vcpu_load_fp(). Note that we also rely on
* the guest's max VL to have been set by fpsimd_lazy_switch_to_host()
* so that any intervening kernel-mode SIMD (NEON or otherwise)
* operation sees the full guest state that needs saving.
*/
if (vcpu_get_flag(vcpu, IN_NESTED_ERET) ||
vcpu_get_flag(vcpu, IN_NESTED_EXCEPTION)) {
WARN_ON_ONCE(host_owns_fp_regs());
return;
}
Annotation
- Immediate include surface: `linux/irqflags.h`, `linux/sched.h`, `linux/kvm_host.h`, `asm/fpsimd.h`, `asm/kvm_asm.h`, `asm/kvm_hyp.h`, `asm/kvm_mmu.h`, `asm/sysreg.h`.
- Detected declarations: `function regs`, `function vcpu_get_flag`, `function preemptible`, `function kvm_arch_vcpu_ctxsync_fp`, `function kvm_arch_vcpu_put_fp`, `function kvm_arch_vcpu_load_fp`.
- Atlas domain: Architecture Layer / arch/arm64.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.