在 2026/5/20 下午2:44, Bibo Mao 写道:


On 2026/5/7 下午5:23, Song Gao wrote:
This patch adds Kvm put/get msgint CSRs and check msgint feature.

Signed-off-by: Song Gao <[email protected]>
---
  target/loongarch/cpu.c     |  5 ++-
  target/loongarch/cpu.h     |  1 +
  target/loongarch/kvm/kvm.c | 69 ++++++++++++++++++++++++++++++++++++++
  3 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index e22568c84a..fe60c9b92b 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -443,9 +443,6 @@ static void loongarch_max_initfn(Object *obj)
        cpu->ptw = ON_OFF_AUTO_AUTO;
      if (tcg_enabled()) {
-        cpu->env.cpucfg[1] = FIELD_DP32(cpu->env.cpucfg[1], CPUCFG1, MSG_INT, 1);
-        cpu->msgint = ON_OFF_AUTO_AUTO;
-
          uint32_t data = cpu->env.cpucfg[2];
          data = FIELD_DP32(data, CPUCFG2, HPTW, 1);
          /* Enable LA v1.1 instructions */
@@ -456,6 +453,8 @@ static void loongarch_max_initfn(Object *obj)
          data = FIELD_DP32(data, CPUCFG2, SCQ, 1);
          cpu->env.cpucfg[2] = data;
      }
+    cpu->env.cpucfg[1] = FIELD_DP32(cpu->env.cpucfg[1], CPUCFG1, MSG_INT, 1);
+    cpu->msgint = ON_OFF_AUTO_AUTO;
  }
    #if defined(CONFIG_KVM)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 096d778928..e6bbcded95 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -301,6 +301,7 @@ enum loongarch_features {
      LOONGARCH_FEATURE_PV_IPI,
      LOONGARCH_FEATURE_STEALTIME,
      LOONGARCH_FEATURE_PTW,
+    LOONGARCH_FEATURE_MSGINT,
  };
    typedef struct  LoongArchBT {
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 9d844c4905..dad260636a 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -35,6 +35,13 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
      KVM_CAP_LAST_INFO
  };
  +static bool kvm_cpu_has_msgint(CPUState *cs)
+{
+    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+
+    return FIELD_EX64(cpu->env.cpucfg[1], CPUCFG1, MSG_INT);
+}
+
  static int kvm_get_stealtime(CPUState *cs)
  {
      CPULoongArchState *env = cpu_env(cs);
@@ -358,6 +365,20 @@ static int kvm_loongarch_get_csr(CPUState *cs)
        ret |= kvm_loongarch_get_pmu(cs);
  +    if (kvm_cpu_has_msgint(cs)) {
Would you like to add some comments that CSR register MSGIS getting must be put after CSR register CSR_ESTAT? Since register CSR_ESTAT will sync software pending MSGINT status to hardware register and modify HW CSR MSGIS registers.

So this piece of code should put after CSR_ESTAT register reading.

I will correct it on v3.

Thanks.
Song Gao
Regards
Bibo Mao

+        ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MSGIS(0)),
+                               &env->CSR_MSGIS[0]);
+
+        ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MSGIS(1)),
+                               &env->CSR_MSGIS[1]);
+
+        ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MSGIS(2)),
+                               &env->CSR_MSGIS[2]);
+
+        ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MSGIS(3)),
+                               &env->CSR_MSGIS[3]);
+    }
+
      ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
                             &env->CSR_TVAL);
  @@ -533,6 +554,20 @@ static int kvm_loongarch_put_csr(CPUState *cs, KvmPutState level)
        ret |= kvm_loongarch_put_pmu(cs);
  +    if (kvm_cpu_has_msgint(cs)) {
+        ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MSGIS(0)),
+                               &env->CSR_MSGIS[0]);
+
+        ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MSGIS(1)),
+                               &env->CSR_MSGIS[1]);
+
+        ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MSGIS(2)),
+                               &env->CSR_MSGIS[2]);
+
+        ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MSGIS(3)),
+                               &env->CSR_MSGIS[3]);
+    }
+
      /*
       * timer cfg must be put at last since it is used to enable
       * guest timer
@@ -982,6 +1017,12 @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
          ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
          return (ret == 0);
  +    case LOONGARCH_FEATURE_MSGINT:
+        attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
+        attr.attr = KVM_LOONGARCH_VM_FEAT_MSGINT;
+        ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
+        return (ret == 0);
+
      default:
          return false;
      }
@@ -1155,6 +1196,28 @@ static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp)
      return 0;
  }
  +static int kvm_cpu_check_msgint(CPUState *cs, Error **errp)
+{
+    CPULoongArchState *env = cpu_env(cs);
+    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+    bool kvm_supported;
+
+    kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_MSGINT);
+    env->cpucfg[1] = FIELD_DP32(env->cpucfg[1], CPUCFG1, MSG_INT, 0);
+    if (cpu->msgint == ON_OFF_AUTO_ON) {
+        if (kvm_supported) {
+            env->cpucfg[1] = FIELD_DP32(env->cpucfg[1], CPUCFG1, MSG_INT, 1);
+        } else {
+            error_setg(errp, "'msgint' feature not supported by KVM on this host");
+            return -ENOTSUP;
+        }
+    } else if ((cpu->msgint == ON_OFF_AUTO_AUTO) && kvm_supported) {
+        env->cpucfg[1] = FIELD_DP32(env->cpucfg[1], CPUCFG1, MSG_INT, 1);
+    }
+
+    return 0;
+}
+
  int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
  {
      return 0;
@@ -1210,6 +1273,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
          return ret;
      }
  +    ret = kvm_cpu_check_msgint(cs, &local_err);
+    if (ret < 0) {
+        error_report_err(local_err);
+        return ret;
+    }
+
      return 0;
  }



Reply via email to