diff mbox series

[v5,3/3] LoongArch: KVM: Add vm migration support for LBT registers

Message ID 20240725033404.2675204-4-maobibo@loongson.cn (mailing list archive)
State New, archived
Headers show
Series LoongArch: KVM: Add Binary Translation extension support | expand

Commit Message

Bibo Mao July 25, 2024, 3:34 a.m. UTC
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: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/include/uapi/asm/kvm.h |  9 +++++
 arch/loongarch/kvm/vcpu.c             | 56 +++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

Comments

kernel test robot July 25, 2024, 1:55 p.m. UTC | #1
Hi Bibo,

kernel test robot noticed the following build errors:

[auto build test ERROR on c33ffdb70cc6df4105160f991288e7d2567d7ffa]

url:    https://github.com/intel-lab-lkp/linux/commits/Bibo-Mao/LoongArch-KVM-Add-HW-Binary-Translation-extension-support/20240725-113707
base:   c33ffdb70cc6df4105160f991288e7d2567d7ffa
patch link:    https://lore.kernel.org/r/20240725033404.2675204-4-maobibo%40loongson.cn
patch subject: [PATCH v5 3/3] LoongArch: KVM: Add vm migration support for LBT registers
config: loongarch-defconfig (https://download.01.org/0day-ci/archive/20240725/202407252157.QONm81J6-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240725/202407252157.QONm81J6-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407252157.QONm81J6-lkp@intel.com/

All errors (new ones prefixed by >>):

   arch/loongarch/kvm/vcpu.c: In function 'kvm_get_one_reg':
>> arch/loongarch/kvm/vcpu.c:606:45: error: assignment to 'long unsigned int' from 'u64 *' {aka 'long long unsigned int *'} makes integer from pointer without a cast [-Wint-conversion]
     606 |                         vcpu->arch.lbt.scr0 = v;
         |                                             ^
   arch/loongarch/kvm/vcpu.c:609:45: error: assignment to 'long unsigned int' from 'u64 *' {aka 'long long unsigned int *'} makes integer from pointer without a cast [-Wint-conversion]
     609 |                         vcpu->arch.lbt.scr1 = v;
         |                                             ^
   arch/loongarch/kvm/vcpu.c:612:45: error: assignment to 'long unsigned int' from 'u64 *' {aka 'long long unsigned int *'} makes integer from pointer without a cast [-Wint-conversion]
     612 |                         vcpu->arch.lbt.scr2 = v;
         |                                             ^
   arch/loongarch/kvm/vcpu.c:615:45: error: assignment to 'long unsigned int' from 'u64 *' {aka 'long long unsigned int *'} makes integer from pointer without a cast [-Wint-conversion]
     615 |                         vcpu->arch.lbt.scr3 = v;
         |                                             ^
   arch/loongarch/kvm/vcpu.c:618:47: error: assignment to 'long unsigned int' from 'u64 *' {aka 'long long unsigned int *'} makes integer from pointer without a cast [-Wint-conversion]
     618 |                         vcpu->arch.lbt.eflags = v;
         |                                               ^
>> arch/loongarch/kvm/vcpu.c:621:45: error: assignment to 'uint32_t' {aka 'unsigned int'} from 'u64 *' {aka 'long long unsigned int *'} makes integer from pointer without a cast [-Wint-conversion]
     621 |                         vcpu->arch.fpu.ftop = v;
         |                                             ^
   arch/loongarch/kvm/vcpu.c: In function 'kvm_set_one_reg':
>> arch/loongarch/kvm/vcpu.c:700:25: error: invalid type argument of unary '*' (have 'u64' {aka 'long long unsigned int'})
     700 |                         *v = vcpu->arch.lbt.scr0;
         |                         ^~
   arch/loongarch/kvm/vcpu.c:703:25: error: invalid type argument of unary '*' (have 'u64' {aka 'long long unsigned int'})
     703 |                         *v = vcpu->arch.lbt.scr1;
         |                         ^~
   arch/loongarch/kvm/vcpu.c:706:25: error: invalid type argument of unary '*' (have 'u64' {aka 'long long unsigned int'})
     706 |                         *v = vcpu->arch.lbt.scr2;
         |                         ^~
   arch/loongarch/kvm/vcpu.c:709:25: error: invalid type argument of unary '*' (have 'u64' {aka 'long long unsigned int'})
     709 |                         *v = vcpu->arch.lbt.scr3;
         |                         ^~
   arch/loongarch/kvm/vcpu.c:712:25: error: invalid type argument of unary '*' (have 'u64' {aka 'long long unsigned int'})
     712 |                         *v = vcpu->arch.lbt.eflags;
         |                         ^~
   arch/loongarch/kvm/vcpu.c:715:25: error: invalid type argument of unary '*' (have 'u64' {aka 'long long unsigned int'})
     715 |                         *v = vcpu->arch.fpu.ftop;
         |                         ^~


vim +606 arch/loongarch/kvm/vcpu.c

   568	
   569	static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
   570			const struct kvm_one_reg *reg, u64 *v)
   571	{
   572		int id, ret = 0;
   573		u64 type = reg->id & KVM_REG_LOONGARCH_MASK;
   574	
   575		switch (type) {
   576		case KVM_REG_LOONGARCH_CSR:
   577			id = KVM_GET_IOC_CSR_IDX(reg->id);
   578			ret = _kvm_getcsr(vcpu, id, v);
   579			break;
   580		case KVM_REG_LOONGARCH_CPUCFG:
   581			id = KVM_GET_IOC_CPUCFG_IDX(reg->id);
   582			if (id >= 0 && id < KVM_MAX_CPUCFG_REGS)
   583				*v = vcpu->arch.cpucfg[id];
   584			else
   585				ret = -EINVAL;
   586			break;
   587		case KVM_REG_LOONGARCH_KVM:
   588			switch (reg->id) {
   589			case KVM_REG_LOONGARCH_COUNTER:
   590				*v = drdtime() + vcpu->kvm->arch.time_offset;
   591				break;
   592			case KVM_REG_LOONGARCH_DEBUG_INST:
   593				*v = INSN_HVCL | KVM_HCALL_SWDBG;
   594				break;
   595			default:
   596				ret = -EINVAL;
   597				break;
   598			}
   599			break;
   600		case KVM_REG_LOONGARCH_LBT:
   601			if (!kvm_guest_has_lbt(&vcpu->arch))
   602				return -ENXIO;
   603	
   604			switch (reg->id) {
   605			case KVM_REG_LOONGARCH_LBT_SCR0:
 > 606				vcpu->arch.lbt.scr0 = v;
   607				break;
   608			case KVM_REG_LOONGARCH_LBT_SCR1:
   609				vcpu->arch.lbt.scr1 = v;
   610				break;
   611			case KVM_REG_LOONGARCH_LBT_SCR2:
   612				vcpu->arch.lbt.scr2 = v;
   613				break;
   614			case KVM_REG_LOONGARCH_LBT_SCR3:
   615				vcpu->arch.lbt.scr3 = v;
   616				break;
   617			case KVM_REG_LOONGARCH_LBT_EFLAGS:
   618				vcpu->arch.lbt.eflags = v;
   619				break;
   620			case KVM_REG_LOONGARCH_LBT_FTOP:
 > 621				vcpu->arch.fpu.ftop = v;
   622				break;
   623			default:
   624				ret = -EINVAL;
   625				break;
   626			}
   627			break;
   628		default:
   629			ret = -EINVAL;
   630			break;
   631		}
   632	
   633		return ret;
   634	}
   635	
   636	static int kvm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
   637	{
   638		int ret = 0;
   639		u64 v, size = reg->id & KVM_REG_SIZE_MASK;
   640	
   641		switch (size) {
   642		case KVM_REG_SIZE_U64:
   643			ret = kvm_get_one_reg(vcpu, reg, &v);
   644			if (ret)
   645				return ret;
   646			ret = put_user(v, (u64 __user *)(long)reg->addr);
   647			break;
   648		default:
   649			ret = -EINVAL;
   650			break;
   651		}
   652	
   653		return ret;
   654	}
   655	
   656	static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
   657				const struct kvm_one_reg *reg, u64 v)
   658	{
   659		int id, ret = 0;
   660		u64 type = reg->id & KVM_REG_LOONGARCH_MASK;
   661	
   662		switch (type) {
   663		case KVM_REG_LOONGARCH_CSR:
   664			id = KVM_GET_IOC_CSR_IDX(reg->id);
   665			ret = _kvm_setcsr(vcpu, id, v);
   666			break;
   667		case KVM_REG_LOONGARCH_CPUCFG:
   668			id = KVM_GET_IOC_CPUCFG_IDX(reg->id);
   669			ret = kvm_check_cpucfg(id, v);
   670			if (ret)
   671				break;
   672			vcpu->arch.cpucfg[id] = (u32)v;
   673			break;
   674		case KVM_REG_LOONGARCH_KVM:
   675			switch (reg->id) {
   676			case KVM_REG_LOONGARCH_COUNTER:
   677				/*
   678				 * gftoffset is relative with board, not vcpu
   679				 * only set for the first time for smp system
   680				 */
   681				if (vcpu->vcpu_id == 0)
   682					vcpu->kvm->arch.time_offset = (signed long)(v - drdtime());
   683				break;
   684			case KVM_REG_LOONGARCH_VCPU_RESET:
   685				kvm_reset_timer(vcpu);
   686				memset(&vcpu->arch.irq_pending, 0, sizeof(vcpu->arch.irq_pending));
   687				memset(&vcpu->arch.irq_clear, 0, sizeof(vcpu->arch.irq_clear));
   688				break;
   689			default:
   690				ret = -EINVAL;
   691				break;
   692			}
   693			break;
   694		case KVM_REG_LOONGARCH_LBT:
   695			if (!kvm_guest_has_lbt(&vcpu->arch))
   696				return -ENXIO;
   697	
   698			switch (reg->id) {
   699			case KVM_REG_LOONGARCH_LBT_SCR0:
 > 700				*v = vcpu->arch.lbt.scr0;
   701				break;
   702			case KVM_REG_LOONGARCH_LBT_SCR1:
   703				*v = vcpu->arch.lbt.scr1;
   704				break;
   705			case KVM_REG_LOONGARCH_LBT_SCR2:
   706				*v = vcpu->arch.lbt.scr2;
   707				break;
   708			case KVM_REG_LOONGARCH_LBT_SCR3:
   709				*v = vcpu->arch.lbt.scr3;
   710				break;
   711			case KVM_REG_LOONGARCH_LBT_EFLAGS:
   712				*v = vcpu->arch.lbt.eflags;
   713				break;
   714			case KVM_REG_LOONGARCH_LBT_FTOP:
   715				*v = vcpu->arch.fpu.ftop;
   716				break;
   717			default:
   718				ret = -EINVAL;
   719				break;
   720			}
   721			break;
   722		default:
   723			ret = -EINVAL;
   724			break;
   725		}
   726	
   727		return ret;
   728	}
   729
diff mbox series

Patch

diff --git a/arch/loongarch/include/uapi/asm/kvm.h b/arch/loongarch/include/uapi/asm/kvm.h
index 49bafac8b22d..003fb766c93f 100644
--- a/arch/loongarch/include/uapi/asm/kvm.h
+++ b/arch/loongarch/include/uapi/asm/kvm.h
@@ -64,6 +64,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
@@ -77,6 +78,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)
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index aeb5f76a86c1..76719bf522b7 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -597,6 +597,34 @@  static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
 			break;
 		}
 		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;
 	default:
 		ret = -EINVAL;
 		break;
@@ -663,6 +691,34 @@  static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
 			break;
 		}
 		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;
 	default:
 		ret = -EINVAL;
 		break;