Commit 9f93e466 authored by Tianrui Zhao's avatar Tianrui Zhao Committed by Xianglai Li
Browse files

LoongArch: KVM: Add LSX (128bit SIMD) support

mainline inclusion
from mainline-v6.8-rc1
commit db1ecca22edf27c5a3dd66af406c88b5b5ac7cc1
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I94LRF


CVE: NA

--------------------------------

This patch adds LSX (128bit SIMD) support for LoongArch KVM.

There will be LSX exception in KVM when guest use the LSX instructions.
KVM will enable LSX and restore the vector registers for guest and then
return to guest to continue running.

Signed-off-by: default avatarTianrui Zhao <zhaotianrui@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
Signed-off-by: default avatarXianglai Li <lixianglai@loongson.cn>
parent 6f0a6d39
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -95,8 +95,9 @@ enum emulation_result {
};

#define KVM_LARCH_FPU		(0x1 << 0)
#define KVM_LARCH_SWCSR_LATEST	(0x1 << 1)
#define KVM_LARCH_HWCSR_USABLE	(0x1 << 2)
#define KVM_LARCH_LSX		(0x1 << 1)
#define KVM_LARCH_SWCSR_LATEST	(0x1 << 2)
#define KVM_LARCH_HWCSR_USABLE	(0x1 << 3)

struct kvm_vcpu_arch {
	/*
@@ -178,6 +179,16 @@ static inline void writel_sw_gcsr(struct loongarch_csrs *csr, int reg, unsigned
	csr->csrs[reg] = val;
}

static inline bool kvm_guest_has_fpu(struct kvm_vcpu_arch *arch)
{
	return arch->cpucfg[2] & CPUCFG2_FP;
}

static inline bool kvm_guest_has_lsx(struct kvm_vcpu_arch *arch)
{
	return arch->cpucfg[2] & CPUCFG2_LSX;
}

/* Debug: dump vcpu state */
int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu);

+10 −0
Original line number Diff line number Diff line
@@ -55,6 +55,16 @@ void kvm_save_fpu(struct loongarch_fpu *fpu);
void kvm_restore_fpu(struct loongarch_fpu *fpu);
void kvm_restore_fcsr(struct loongarch_fpu *fpu);

#ifdef CONFIG_CPU_HAS_LSX
int kvm_own_lsx(struct kvm_vcpu *vcpu);
void kvm_save_lsx(struct loongarch_fpu *fpu);
void kvm_restore_lsx(struct loongarch_fpu *fpu);
#else
static inline int kvm_own_lsx(struct kvm_vcpu *vcpu) { }
static inline void kvm_save_lsx(struct loongarch_fpu *fpu) { }
static inline void kvm_restore_lsx(struct loongarch_fpu *fpu) { }
#endif

void kvm_init_timer(struct kvm_vcpu *vcpu, unsigned long hz);
void kvm_reset_timer(struct kvm_vcpu *vcpu);
void kvm_save_timer(struct kvm_vcpu *vcpu);
+1 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ struct kvm_fpu {
#define LOONGARCH_REG_64(TYPE, REG)	(TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT))
#define KVM_IOC_CSRID(REG)		LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG)
#define KVM_IOC_CPUCFG(REG)		LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)
#define KVM_LOONGARCH_VCPU_CPUCFG	0

struct kvm_debug_exit_arch {
};
+1 −0
Original line number Diff line number Diff line
@@ -349,6 +349,7 @@ SYM_FUNC_START(_restore_lsx_upper)
	lsx_restore_all_upper a0 t0 t1
	jr	ra
SYM_FUNC_END(_restore_lsx_upper)
EXPORT_SYMBOL(_restore_lsx_upper)

SYM_FUNC_START(_init_lsx_upper)
	lsx_init_all_upper t1
+21 −0
Original line number Diff line number Diff line
@@ -634,6 +634,11 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu)
{
	struct kvm_run *run = vcpu->run;

	if (!kvm_guest_has_fpu(&vcpu->arch)) {
		kvm_queue_exception(vcpu, EXCCODE_INE, 0);
		return RESUME_GUEST;
	}

	/*
	 * If guest FPU not present, the FPU operation should have been
	 * treated as a reserved instruction!
@@ -650,6 +655,21 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu)
	return RESUME_GUEST;
}

/*
 * kvm_handle_lsx_disabled() - Guest used LSX while disabled in root.
 * @vcpu:      Virtual CPU context.
 *
 * Handle when the guest attempts to use LSX when it is disabled in the root
 * context.
 */
static int kvm_handle_lsx_disabled(struct kvm_vcpu *vcpu)
{
	if (kvm_own_lsx(vcpu))
		kvm_queue_exception(vcpu, EXCCODE_INE, 0);

	return RESUME_GUEST;
}

/*
 * LoongArch KVM callback handling for unimplemented guest exiting
 */
@@ -678,6 +698,7 @@ static exit_handle_fn kvm_fault_tables[EXCCODE_INT_START] = {
	[EXCCODE_TLBS]			= kvm_handle_write_fault,
	[EXCCODE_TLBM]			= kvm_handle_write_fault,
	[EXCCODE_FPDIS]			= kvm_handle_fpu_disabled,
	[EXCCODE_LSXDIS]		= kvm_handle_lsx_disabled,
	[EXCCODE_GSPR]			= kvm_handle_gspr,
};

Loading