On 2025/10/15 下午3:27, Song Gao wrote:
This patch adds set/get msgint CSRs and check msgint feature.

Signed-off-by: Song Gao <[email protected]>
---
RFC: this patch need update linux-headers and
the linux kernel kvm support avec(not merged).

  linux-headers/asm-loongarch/kvm.h |  1 +
  target/loongarch/cpu.h            |  1 +
  target/loongarch/kvm/kvm.c        | 59 ++++++++++++++++++++++++++++++-
  3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/linux-headers/asm-loongarch/kvm.h 
b/linux-headers/asm-loongarch/kvm.h
index 5f354f5c68..20e69561bf 100644
--- a/linux-headers/asm-loongarch/kvm.h
+++ b/linux-headers/asm-loongarch/kvm.h
@@ -103,6 +103,7 @@ struct kvm_fpu {
  #define  KVM_LOONGARCH_VM_FEAT_PMU            5
  #define  KVM_LOONGARCH_VM_FEAT_PV_IPI         6
  #define  KVM_LOONGARCH_VM_FEAT_PV_STEALTIME   7
+#define  KVM_LOONGARCH_VM_FEAT_MSGINT           8
/* Device Control API on vcpu fd */
  #define KVM_LOONGARCH_VCPU_CPUCFG     0
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index b8e3b46c3a..e714b4252e 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -278,6 +278,7 @@ enum loongarch_features {
      LOONGARCH_FEATURE_PMU,
      LOONGARCH_FEATURE_PV_IPI,
      LOONGARCH_FEATURE_STEALTIME,
+    LOONGARCH_FEATURE_MSGINT,
  };
typedef struct LoongArchBT {
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 4e4f4e79f6..7c48787d97 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -316,6 +316,18 @@ static int kvm_loongarch_get_csr(CPUState *cs)
      ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
                             &env->CSR_DMW[3]);
+ 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]);
+
It will better if there will msgint feature checking such as msgint_needed().

static bool msgint_needed(void *opaque)
{
    LoongArchCPU *cpu = opaque;

    return FIELD_EX64(cpu->env.cpucfg[1], CPUCFG1, MSG_INT);
}
      ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
                             &env->CSR_TVAL);
@@ -488,6 +500,19 @@ static int kvm_loongarch_put_csr(CPUState *cs, KvmPutState level) ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
                             &env->CSR_DMW[3]);
+
+    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]);
+
Ditto
      /*
       * timer cfg must be put at last since it is used to enable
       * guest timer
@@ -930,7 +955,11 @@ static bool kvm_feature_supported(CPUState *cs, enum 
loongarch_features feature)
          attr.attr = KVM_LOONGARCH_VM_FEAT_PV_STEALTIME;
          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);
Space line needed here :)

      default:
          return false;
      }
@@ -1074,6 +1103,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) {
When is its value set with ON_OFF_AUTO_AUTO in KVM mode? It seems that all is ON_OFF_AUTO_OFF by default in KVM mode.

Regards
Bibo Mao
+        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;
@@ -1123,6 +1174,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;
  }
base-commit: 3bf5c57a11827d9fa706524d57ee3e5af68a429e



Reply via email to