summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBibo Mao <maobibo@loongson.cn>2025-02-17 09:37:11 +0800
committerBibo Mao <maobibo@loongson.cn>2025-02-25 16:05:31 +0800
commit2698cc7c99b50cf4bb127c56e5c90f7f3cba6f0d (patch)
tree527bd3c9cf5ea06f0d3bb9aaa890cac9e43d41f3
parent620d9bd0022e011147c1133ef542c45a0da962e4 (diff)
downloadfocaccia-qemu-2698cc7c99b50cf4bb127c56e5c90f7f3cba6f0d.tar.gz
focaccia-qemu-2698cc7c99b50cf4bb127c56e5c90f7f3cba6f0d.zip
target/loongarch: Enable paravirt ipi feature
The similiar with cpucfg register, paravirt ipi feature is set in
function kvm_arch_put_registers(). Instead the paravirt feature can
be enabled only once, it cannot be changed dynamically.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Diffstat (limited to '')
-rw-r--r--target/loongarch/kvm/kvm.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 3117441f53..ed0706e8e0 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -83,6 +83,33 @@ static int kvm_set_stealtime(CPUState *cs)
     return 0;
 }
 
+static int kvm_set_pv_features(CPUState *cs)
+{
+    CPULoongArchState *env = cpu_env(cs);
+    int err;
+    uint64_t val;
+    struct kvm_device_attr attr = {
+        .group = KVM_LOONGARCH_VCPU_CPUCFG,
+        .attr = CPUCFG_KVM_FEATURE,
+        .addr = (uint64_t)&val,
+    };
+
+    err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
+    if (err) {
+        return 0;
+    }
+
+    val = env->pv_features;
+    err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
+    if (err) {
+        error_report("Fail to set pv feature "TARGET_FMT_lx " with error %s",
+                      val, strerror(errno));
+        return err;
+    }
+
+    return 0;
+}
+
 static int kvm_loongarch_get_regs_core(CPUState *cs)
 {
     int ret = 0;
@@ -738,6 +765,7 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp)
 int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
 {
     int ret;
+    static int once;
 
     ret = kvm_loongarch_put_regs_core(cs);
     if (ret) {
@@ -764,6 +792,14 @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
         return ret;
     }
 
+    if (!once) {
+        ret = kvm_set_pv_features(cs);
+        if (ret) {
+            return ret;
+        }
+        once = 1;
+    }
+
     if (level >= KVM_PUT_FULL_STATE) {
         /*
          * only KVM_PUT_FULL_STATE is required, kvm kernel will clear