]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
LoongArch: KVM: Implement fpu operations for vcpu
authorTianrui Zhao <zhaotianrui@loongson.cn>
Mon, 2 Oct 2023 02:01:28 +0000 (10:01 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Mon, 2 Oct 2023 02:01:28 +0000 (10:01 +0800)
Implement LoongArch fpu related interface for vcpu, such as get fpu, set
fpu, own fpu and lose fpu, etc.

Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Tested-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kvm/vcpu.c

index 4870655659096442a2021d81382de9635a5498e4..0f19c8b0c02869bad667d10eebf8c4cf0b68c5d1 100644 (file)
@@ -402,6 +402,62 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
        return r;
 }
 
+int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+       int i = 0;
+
+       fpu->fcc = vcpu->arch.fpu.fcc;
+       fpu->fcsr = vcpu->arch.fpu.fcsr;
+       for (i = 0; i < NUM_FPU_REGS; i++)
+               memcpy(&fpu->fpr[i], &vcpu->arch.fpu.fpr[i], FPU_REG_WIDTH / 64);
+
+       return 0;
+}
+
+int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+       int i = 0;
+
+       vcpu->arch.fpu.fcc = fpu->fcc;
+       vcpu->arch.fpu.fcsr = fpu->fcsr;
+       for (i = 0; i < NUM_FPU_REGS; i++)
+               memcpy(&vcpu->arch.fpu.fpr[i], &fpu->fpr[i], FPU_REG_WIDTH / 64);
+
+       return 0;
+}
+
+/* Enable FPU and restore context */
+void kvm_own_fpu(struct kvm_vcpu *vcpu)
+{
+       preempt_disable();
+
+       /* Enable FPU */
+       set_csr_euen(CSR_EUEN_FPEN);
+
+       kvm_restore_fpu(&vcpu->arch.fpu);
+       vcpu->arch.aux_inuse |= KVM_LARCH_FPU;
+       trace_kvm_aux(vcpu, KVM_TRACE_AUX_RESTORE, KVM_TRACE_AUX_FPU);
+
+       preempt_enable();
+}
+
+/* Save context and disable FPU */
+void kvm_lose_fpu(struct kvm_vcpu *vcpu)
+{
+       preempt_disable();
+
+       if (vcpu->arch.aux_inuse & KVM_LARCH_FPU) {
+               kvm_save_fpu(&vcpu->arch.fpu);
+               vcpu->arch.aux_inuse &= ~KVM_LARCH_FPU;
+               trace_kvm_aux(vcpu, KVM_TRACE_AUX_SAVE, KVM_TRACE_AUX_FPU);
+
+               /* Disable FPU */
+               clear_csr_euen(CSR_EUEN_FPEN);
+       }
+
+       preempt_enable();
+}
+
 int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
 {
        return 0;