]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
LoongArch: KVM: Add vm migration support for LBT registers
authorBibo Mao <maobibo@loongson.cn>
Wed, 11 Sep 2024 15:26:32 +0000 (23:26 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Wed, 11 Sep 2024 15:26:32 +0000 (23:26 +0800)
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>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/uapi/asm/kvm.h
arch/loongarch/kvm/vcpu.c

index 49bafac8b22d343cc51b88d7b4afc100e59cf6e4..003fb766c93f710d3071f9713c12594a32960f63 100644 (file)
@@ -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)
index 8b45f6ad78544e2eb6625d5332a704d970762f7c..6906babf27c6df3bb6842c0c8108c118c8279167 100644 (file)
@@ -584,6 +584,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:
@@ -643,6 +671,34 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
                        break;
                vcpu->arch.cpucfg[id] = (u32)v;
                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: