There are different structures with LBT and FPU register restore, with LBT the structure is vcpu::arch::lbt, with FPU the structure is vcpu::arch::fpu. And FPU/LSX/LASX saving and restoring share the common structure vcpu::arch::fpu. New request bit KVM_REQ_LBT_LOAD is used for LBT register restore. Signed-off-by: Bibo Mao --- arch/loongarch/include/asm/kvm_host.h | 1 + arch/loongarch/kvm/exit.c | 6 ++---- arch/loongarch/kvm/vcpu.c | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index 19eb5e5c3984..035e698309d0 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -38,6 +38,7 @@ #define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(1) #define KVM_REQ_PMU KVM_ARCH_REQ(2) #define KVM_REQ_AUX_LOAD KVM_ARCH_REQ(3) +#define KVM_REQ_LBT_LOAD KVM_ARCH_REQ(4) #define KVM_GUESTDBG_SW_BP_MASK \ (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP) diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c index da0ad89f2eb7..3e06a66a90f8 100644 --- a/arch/loongarch/kvm/exit.c +++ b/arch/loongarch/kvm/exit.c @@ -827,10 +827,8 @@ static int kvm_handle_lbt_disabled(struct kvm_vcpu *vcpu, int ecode) { if (!kvm_guest_has_lbt(&vcpu->arch)) kvm_queue_exception(vcpu, EXCCODE_INE, 0); - else { - vcpu->arch.aux_ldtype = KVM_LARCH_LBT; - kvm_make_request(KVM_REQ_AUX_LOAD, vcpu); - } + else + kvm_make_request(KVM_REQ_LBT_LOAD, vcpu); return RESUME_GUEST; } diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 831f381a8fd1..2f2c1cbe127c 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -249,15 +249,15 @@ static void kvm_late_check_requests(struct kvm_vcpu *vcpu) case KVM_LARCH_LASX: kvm_own_lasx(vcpu); break; - case KVM_LARCH_LBT: - kvm_own_lbt(vcpu); - break; default: break; } vcpu->arch.aux_ldtype = 0; } + + if (kvm_check_request(KVM_REQ_LBT_LOAD, vcpu)) + kvm_own_lbt(vcpu); } /* -- 2.39.3 There are three FPU type FPU/LSX/LASX representing FPU64, FPU128 and FPU256, and now lazy FPU method is used with FPU enabling. There are three different HW FPU exception code with different FPU type. The exising method is to enable specified FPU type with responding FPU exeception. Supposing application uses FPU64 and FPU256, there will be FPU256 exception when FPU256 type is used. Here enable FPU with VM supported type directly, it can avoid unnecessary FPU exception in future if further FPU type is used. Signed-off-by: Bibo Mao --- arch/loongarch/include/asm/kvm_host.h | 1 - arch/loongarch/kvm/exit.c | 9 ++------- arch/loongarch/kvm/vcpu.c | 19 +++++-------------- 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index 035e698309d0..7cd883a8281f 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -203,7 +203,6 @@ struct kvm_vcpu_arch { /* Which auxiliary state is loaded (KVM_LARCH_*) */ unsigned int aux_inuse; - unsigned int aux_ldtype; /* FPU state */ struct loongarch_fpu fpu FPU_ALIGN; diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c index 3e06a66a90f8..ddc3f4cc510b 100644 --- a/arch/loongarch/kvm/exit.c +++ b/arch/loongarch/kvm/exit.c @@ -754,7 +754,6 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu, int ecode) return RESUME_HOST; } - vcpu->arch.aux_ldtype = KVM_LARCH_FPU; kvm_make_request(KVM_REQ_AUX_LOAD, vcpu); return RESUME_GUEST; @@ -795,10 +794,8 @@ static int kvm_handle_lsx_disabled(struct kvm_vcpu *vcpu, int ecode) { if (!kvm_guest_has_lsx(&vcpu->arch)) kvm_queue_exception(vcpu, EXCCODE_INE, 0); - else { - vcpu->arch.aux_ldtype = KVM_LARCH_LSX; + else kvm_make_request(KVM_REQ_AUX_LOAD, vcpu); - } return RESUME_GUEST; } @@ -815,10 +812,8 @@ static int kvm_handle_lasx_disabled(struct kvm_vcpu *vcpu, int ecode) { if (!kvm_guest_has_lasx(&vcpu->arch)) kvm_queue_exception(vcpu, EXCCODE_INE, 0); - else { - vcpu->arch.aux_ldtype = KVM_LARCH_LASX; + else kvm_make_request(KVM_REQ_AUX_LOAD, vcpu); - } return RESUME_GUEST; } diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 2f2c1cbe127c..144e26e1ed68 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -239,21 +239,12 @@ static void kvm_late_check_requests(struct kvm_vcpu *vcpu) } if (kvm_check_request(KVM_REQ_AUX_LOAD, vcpu)) { - switch (vcpu->arch.aux_ldtype) { - case KVM_LARCH_FPU: - kvm_own_fpu(vcpu); - break; - case KVM_LARCH_LSX: - kvm_own_lsx(vcpu); - break; - case KVM_LARCH_LASX: + if (kvm_guest_has_lasx(&vcpu->arch)) kvm_own_lasx(vcpu); - break; - default: - break; - } - - vcpu->arch.aux_ldtype = 0; + else if (kvm_guest_has_lsx(&vcpu->arch)) + kvm_own_lsx(vcpu); + else + kvm_own_fpu(vcpu); } if (kvm_check_request(KVM_REQ_LBT_LOAD, vcpu)) -- 2.39.3 Request bit KVM_REQ_AUX_LOAD is used for FPU/LSX/LASX register restore, here rename it with KVM_REQ_FPU_LOAD. Signed-off-by: Bibo Mao --- arch/loongarch/include/asm/kvm_host.h | 2 +- arch/loongarch/kvm/exit.c | 6 +++--- arch/loongarch/kvm/vcpu.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index 7cd883a8281f..9e0568c3c7f9 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -37,7 +37,7 @@ #define KVM_REQ_TLB_FLUSH_GPA KVM_ARCH_REQ(0) #define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(1) #define KVM_REQ_PMU KVM_ARCH_REQ(2) -#define KVM_REQ_AUX_LOAD KVM_ARCH_REQ(3) +#define KVM_REQ_FPU_LOAD KVM_ARCH_REQ(3) #define KVM_REQ_LBT_LOAD KVM_ARCH_REQ(4) #define KVM_GUESTDBG_SW_BP_MASK \ diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c index ddc3f4cc510b..07426682929a 100644 --- a/arch/loongarch/kvm/exit.c +++ b/arch/loongarch/kvm/exit.c @@ -754,7 +754,7 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu, int ecode) return RESUME_HOST; } - kvm_make_request(KVM_REQ_AUX_LOAD, vcpu); + kvm_make_request(KVM_REQ_FPU_LOAD, vcpu); return RESUME_GUEST; } @@ -795,7 +795,7 @@ static int kvm_handle_lsx_disabled(struct kvm_vcpu *vcpu, int ecode) if (!kvm_guest_has_lsx(&vcpu->arch)) kvm_queue_exception(vcpu, EXCCODE_INE, 0); else - kvm_make_request(KVM_REQ_AUX_LOAD, vcpu); + kvm_make_request(KVM_REQ_FPU_LOAD, vcpu); return RESUME_GUEST; } @@ -813,7 +813,7 @@ static int kvm_handle_lasx_disabled(struct kvm_vcpu *vcpu, int ecode) if (!kvm_guest_has_lasx(&vcpu->arch)) kvm_queue_exception(vcpu, EXCCODE_INE, 0); else - kvm_make_request(KVM_REQ_AUX_LOAD, vcpu); + kvm_make_request(KVM_REQ_FPU_LOAD, vcpu); return RESUME_GUEST; } diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 144e26e1ed68..553881e326eb 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -238,7 +238,7 @@ static void kvm_late_check_requests(struct kvm_vcpu *vcpu) vcpu->arch.flush_gpa = INVALID_GPA; } - if (kvm_check_request(KVM_REQ_AUX_LOAD, vcpu)) { + if (kvm_check_request(KVM_REQ_FPU_LOAD, vcpu)) { if (kvm_guest_has_lasx(&vcpu->arch)) kvm_own_lasx(vcpu); else if (kvm_guest_has_lsx(&vcpu->arch)) -- 2.39.3 With max VM supported FPU type enabled, if VM supports LASX, there is FPU none --> LASX, no middle FPU state such as FPU --> LASX or LSX --> LASX. Here remove the middle FPU states in function kvm_own_lsx() and kvm_own_lasx(). And it becomes simpler than before. Signed-off-by: Bibo Mao --- arch/loongarch/kvm/vcpu.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 553881e326eb..8c3d6e1a5ed2 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -1390,21 +1390,7 @@ int kvm_own_lsx(struct kvm_vcpu *vcpu) /* Enable LSX for guest */ kvm_check_fcsr(vcpu, vcpu->arch.fpu.fcsr); set_csr_euen(CSR_EUEN_LSXEN | CSR_EUEN_FPEN); - switch (vcpu->arch.aux_inuse & KVM_LARCH_FPU) { - case KVM_LARCH_FPU: - /* - * Guest FPU state already loaded, - * only restore upper LSX state - */ - _restore_lsx_upper(&vcpu->arch.fpu); - break; - default: - /* Neither FP or LSX already active, - * restore full LSX state - */ - kvm_restore_lsx(&vcpu->arch.fpu); - break; - } + kvm_restore_lsx(&vcpu->arch.fpu); trace_kvm_aux(vcpu, KVM_TRACE_AUX_RESTORE, KVM_TRACE_AUX_LSX); vcpu->arch.aux_inuse |= KVM_LARCH_LSX | KVM_LARCH_FPU; @@ -1419,22 +1405,8 @@ int kvm_own_lasx(struct kvm_vcpu *vcpu) { kvm_check_fcsr(vcpu, vcpu->arch.fpu.fcsr); set_csr_euen(CSR_EUEN_FPEN | CSR_EUEN_LSXEN | CSR_EUEN_LASXEN); - switch (vcpu->arch.aux_inuse & (KVM_LARCH_FPU | KVM_LARCH_LSX)) { - case KVM_LARCH_LSX: - case KVM_LARCH_LSX | KVM_LARCH_FPU: - /* Guest LSX state already loaded, only restore upper LASX state */ - _restore_lasx_upper(&vcpu->arch.fpu); - break; - case KVM_LARCH_FPU: - /* Guest FP state already loaded, only restore upper LSX & LASX state */ - _restore_lsx_upper(&vcpu->arch.fpu); - _restore_lasx_upper(&vcpu->arch.fpu); - break; - default: - /* Neither FP or LSX already active, restore full LASX state */ - kvm_restore_lasx(&vcpu->arch.fpu); - break; - } + /* Neither FP or LSX already active, restore full LASX state */ + kvm_restore_lasx(&vcpu->arch.fpu); trace_kvm_aux(vcpu, KVM_TRACE_AUX_RESTORE, KVM_TRACE_AUX_LASX); vcpu->arch.aux_inuse |= KVM_LARCH_LASX | KVM_LARCH_LSX | KVM_LARCH_FPU; -- 2.39.3 In kvm_lose_fpu() FPU state will save in vcpu::arch::fpu, its FPU state comes from vcpu->arch.aux_inuse. Instead existing API vm_guest_has_xxx() can be used also, and bit KVM_LARCH_LASX and KVM_LARCH_LSX in arch.aux_inuse can be removed. Signed-off-by: Bibo Mao --- arch/loongarch/kvm/vcpu.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 8c3d6e1a5ed2..920f3101ed3d 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -1418,24 +1418,27 @@ int kvm_own_lasx(struct kvm_vcpu *vcpu) /* Save context and disable FPU */ void kvm_lose_fpu(struct kvm_vcpu *vcpu) { + if (!(vcpu->arch.aux_inuse & KVM_LARCH_FPU)) + return; + preempt_disable(); kvm_check_fcsr_alive(vcpu); - if (vcpu->arch.aux_inuse & KVM_LARCH_LASX) { + if (kvm_guest_has_lasx(&vcpu->arch)) { kvm_save_lasx(&vcpu->arch.fpu); vcpu->arch.aux_inuse &= ~(KVM_LARCH_LSX | KVM_LARCH_FPU | KVM_LARCH_LASX); trace_kvm_aux(vcpu, KVM_TRACE_AUX_SAVE, KVM_TRACE_AUX_LASX); /* Disable LASX & LSX & FPU */ clear_csr_euen(CSR_EUEN_FPEN | CSR_EUEN_LSXEN | CSR_EUEN_LASXEN); - } else if (vcpu->arch.aux_inuse & KVM_LARCH_LSX) { + } else if (kvm_guest_has_lsx(&vcpu->arch)) { kvm_save_lsx(&vcpu->arch.fpu); vcpu->arch.aux_inuse &= ~(KVM_LARCH_LSX | KVM_LARCH_FPU); trace_kvm_aux(vcpu, KVM_TRACE_AUX_SAVE, KVM_TRACE_AUX_LSX); /* Disable LSX & FPU */ clear_csr_euen(CSR_EUEN_FPEN | CSR_EUEN_LSXEN); - } else if (vcpu->arch.aux_inuse & KVM_LARCH_FPU) { + } else { 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); -- 2.39.3 Bit KVM_LARCH_LASX and KVM_LARCH_LSX represents whether LASX/LSX is enabled. Instead combination of KVM_LARCH_FPU and kvm_guest_has_lasx() has the same effect. Here remove KVM_LARCH_LASX and KVM_LARCH_LSX, make the logic simpler. Signed-off-by: Bibo Mao --- arch/loongarch/include/asm/kvm_host.h | 2 -- arch/loongarch/kvm/vcpu.c | 8 +++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index 9e0568c3c7f9..4a481589ddb2 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -157,8 +157,6 @@ enum emulation_result { }; #define KVM_LARCH_FPU (0x1 << 0) -#define KVM_LARCH_LSX (0x1 << 1) -#define KVM_LARCH_LASX (0x1 << 2) #define KVM_LARCH_LBT (0x1 << 3) #define KVM_LARCH_PMU (0x1 << 4) #define KVM_LARCH_SWCSR_LATEST (0x1 << 5) diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 920f3101ed3d..9a8f026275a5 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -1393,7 +1393,7 @@ int kvm_own_lsx(struct kvm_vcpu *vcpu) kvm_restore_lsx(&vcpu->arch.fpu); trace_kvm_aux(vcpu, KVM_TRACE_AUX_RESTORE, KVM_TRACE_AUX_LSX); - vcpu->arch.aux_inuse |= KVM_LARCH_LSX | KVM_LARCH_FPU; + vcpu->arch.aux_inuse |= KVM_LARCH_FPU; return 0; } @@ -1409,7 +1409,7 @@ int kvm_own_lasx(struct kvm_vcpu *vcpu) kvm_restore_lasx(&vcpu->arch.fpu); trace_kvm_aux(vcpu, KVM_TRACE_AUX_RESTORE, KVM_TRACE_AUX_LASX); - vcpu->arch.aux_inuse |= KVM_LARCH_LASX | KVM_LARCH_LSX | KVM_LARCH_FPU; + vcpu->arch.aux_inuse |= KVM_LARCH_FPU; return 0; } @@ -1426,26 +1426,24 @@ void kvm_lose_fpu(struct kvm_vcpu *vcpu) kvm_check_fcsr_alive(vcpu); if (kvm_guest_has_lasx(&vcpu->arch)) { kvm_save_lasx(&vcpu->arch.fpu); - vcpu->arch.aux_inuse &= ~(KVM_LARCH_LSX | KVM_LARCH_FPU | KVM_LARCH_LASX); trace_kvm_aux(vcpu, KVM_TRACE_AUX_SAVE, KVM_TRACE_AUX_LASX); /* Disable LASX & LSX & FPU */ clear_csr_euen(CSR_EUEN_FPEN | CSR_EUEN_LSXEN | CSR_EUEN_LASXEN); } else if (kvm_guest_has_lsx(&vcpu->arch)) { kvm_save_lsx(&vcpu->arch.fpu); - vcpu->arch.aux_inuse &= ~(KVM_LARCH_LSX | KVM_LARCH_FPU); trace_kvm_aux(vcpu, KVM_TRACE_AUX_SAVE, KVM_TRACE_AUX_LSX); /* Disable LSX & FPU */ clear_csr_euen(CSR_EUEN_FPEN | CSR_EUEN_LSXEN); } else { 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); } + vcpu->arch.aux_inuse &= ~KVM_LARCH_FPU; kvm_lose_lbt(vcpu); preempt_enable(); -- 2.39.3