Commit 7a6231f2 authored by Bibo Mao's avatar Bibo Mao Committed by Xianglai Li
Browse files

LoongArch: KVM: Add vm migration support for LBT registers

mainline inclusion
from mainline-v6.12-rc1
commit acc7f20d54a3eeceec7602b11d6e3462e7fba862
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IAZJDO


CVE: NA

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

Every vcpu has separate LBT registers. And there are four scr registers,
one flags and ftop register for LBT extension. When VM migrates, VMM
needs to get LBT registers for every vcpu.

Here macro KVM_REG_LOONGARCH_LBT is added for new vcpu lbt register type,
the following macro is added to get/put LBT registers.
  KVM_REG_LOONGARCH_LBT_SCR0
  KVM_REG_LOONGARCH_LBT_SCR1
  KVM_REG_LOONGARCH_LBT_SCR2
  KVM_REG_LOONGARCH_LBT_SCR3
  KVM_REG_LOONGARCH_LBT_EFLAGS
  KVM_REG_LOONGARCH_LBT_FTOP

Signed-off-by: default avatarBibo Mao <maobibo@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
Signed-off-by: default avatarXianglai Li <lixianglai@loongson.cn>
parent c73bd2e0
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ struct kvm_fpu {
#define KVM_REG_LOONGARCH_KVM		(KVM_REG_LOONGARCH | 0x20000ULL)
#define KVM_REG_LOONGARCH_FPSIMD	(KVM_REG_LOONGARCH | 0x30000ULL)
#define KVM_REG_LOONGARCH_CPUCFG	(KVM_REG_LOONGARCH | 0x40000ULL)
#define KVM_REG_LOONGARCH_LBT		(KVM_REG_LOONGARCH | 0x50000ULL)
#define KVM_REG_LOONGARCH_MASK		(KVM_REG_LOONGARCH | 0x70000ULL)
#define KVM_CSR_IDX_MASK		0x7fff
#define KVM_CPUCFG_IDX_MASK		0x7fff
@@ -80,6 +81,14 @@ struct kvm_fpu {
/* Debugging: Special instruction for software breakpoint */
#define KVM_REG_LOONGARCH_DEBUG_INST	(KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3)

/* LBT registers */
#define KVM_REG_LOONGARCH_LBT_SCR0	(KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1)
#define KVM_REG_LOONGARCH_LBT_SCR1	(KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2)
#define KVM_REG_LOONGARCH_LBT_SCR2	(KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3)
#define KVM_REG_LOONGARCH_LBT_SCR3	(KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4)
#define KVM_REG_LOONGARCH_LBT_EFLAGS	(KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5)
#define KVM_REG_LOONGARCH_LBT_FTOP	(KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6)

#define LOONGARCH_REG_SHIFT		3
#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)
+56 −0
Original line number Diff line number Diff line
@@ -803,6 +803,34 @@ static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
		else
			ret = -EINVAL;
		break;
	case KVM_REG_LOONGARCH_LBT:
		if (!kvm_guest_has_lbt(&vcpu->arch))
			return -ENXIO;

		switch (reg->id) {
		case KVM_REG_LOONGARCH_LBT_SCR0:
			*v = vcpu->arch.lbt.scr0;
			break;
		case KVM_REG_LOONGARCH_LBT_SCR1:
			*v = vcpu->arch.lbt.scr1;
			break;
		case KVM_REG_LOONGARCH_LBT_SCR2:
			*v = vcpu->arch.lbt.scr2;
			break;
		case KVM_REG_LOONGARCH_LBT_SCR3:
			*v = vcpu->arch.lbt.scr3;
			break;
		case KVM_REG_LOONGARCH_LBT_EFLAGS:
			*v = vcpu->arch.lbt.eflags;
			break;
		case KVM_REG_LOONGARCH_LBT_FTOP:
			*v = vcpu->arch.fpu.ftop;
			break;
		default:
			ret = -EINVAL;
			break;
		}
		break;
	case KVM_REG_LOONGARCH_KVM:
		switch (reg->id) {
		case KVM_REG_LOONGARCH_COUNTER:
@@ -866,6 +894,34 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
							2 * kvm_get_pmu_num(&vcpu->arch) + 1;
		}
		break;
	case KVM_REG_LOONGARCH_LBT:
		if (!kvm_guest_has_lbt(&vcpu->arch))
			return -ENXIO;

		switch (reg->id) {
		case KVM_REG_LOONGARCH_LBT_SCR0:
			vcpu->arch.lbt.scr0 = v;
			break;
		case KVM_REG_LOONGARCH_LBT_SCR1:
			vcpu->arch.lbt.scr1 = v;
			break;
		case KVM_REG_LOONGARCH_LBT_SCR2:
			vcpu->arch.lbt.scr2 = v;
			break;
		case KVM_REG_LOONGARCH_LBT_SCR3:
			vcpu->arch.lbt.scr3 = v;
			break;
		case KVM_REG_LOONGARCH_LBT_EFLAGS:
			vcpu->arch.lbt.eflags = v;
			break;
		case KVM_REG_LOONGARCH_LBT_FTOP:
			vcpu->arch.fpu.ftop = v;
			break;
		default:
			ret = -EINVAL;
			break;
		}
		break;
	case KVM_REG_LOONGARCH_KVM:
		switch (reg->id) {
		case KVM_REG_LOONGARCH_COUNTER: