diff mbox series

[RFC] target/loongarch: Add steal time physical address in vmstate

Message ID 20240527093830.846000-1-maobibo@loongson.cn
State New
Headers show
Series [RFC] target/loongarch: Add steal time physical address in vmstate | expand

Commit Message

maobibo May 27, 2024, 9:38 a.m. UTC
With pv steal time supported, VM machine needs get physical address
of each vcpu and notify to new host during migration. Here two
functions kvm_loongarch_get_stealtime/kvm_loongarch_put_stealtime
are provided and they are called in cpu_pre_save/cpu_post_load
separately.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 target/loongarch/cpu.h               |  3 ++
 target/loongarch/kvm/kvm.c           | 49 ++++++++++++++++++++++++++++
 target/loongarch/kvm/kvm_loongarch.h | 12 +++++++
 target/loongarch/machine.c           | 24 +++++++++++++-
 4 files changed, 87 insertions(+), 1 deletion(-)


base-commit: ffdd099a782556b9ead26551a6f1d070a595306d
diff mbox series

Patch

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 8fc99b8ee8..66e9dd227e 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -390,6 +390,9 @@  typedef struct CPUArchState {
 
     struct loongarch_boot_info *boot_info;
 #endif
+    struct {
+        uint64_t guest_addr;
+    } st;
 } CPULoongArchState;
 
 /**
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index c9c240a573..c7f1b262dd 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -626,6 +626,55 @@  static int kvm_loongarch_put_cpucfg(CPUState *cs)
     return ret;
 }
 
+int kvm_loongarch_get_stealtime(LoongArchCPU *cpu)
+{
+    CPULoongArchState *env = &cpu->env;
+    int err;
+    struct kvm_device_attr attr = {
+        .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL,
+        .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA,
+        .addr = (uint64_t)&env->st.guest_addr,
+    };
+
+    err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr);
+    if (err) {
+        return 0;
+    }
+
+    err = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_DEVICE_ATTR, attr);
+    if (err) {
+        error_report("PVTIME: KVM_GET_DEVICE_ATTR: %s", strerror(errno));
+        return err;
+    }
+
+    return 0;
+}
+
+int kvm_loongarch_put_stealtime(LoongArchCPU *cpu)
+{
+    CPULoongArchState *env = &cpu->env;
+    int err;
+    struct kvm_device_attr attr = {
+        .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL,
+        .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA,
+        .addr = (uint64_t)&env->st.guest_addr,
+    };
+
+    err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr);
+    if (err) {
+        return 0;
+    }
+
+    err = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_DEVICE_ATTR, attr);
+    if (err) {
+        error_report("PVTIME: KVM_SET_DEVICE_ATTR %s with gpa "TARGET_FMT_lx,
+                      strerror(errno), env->st.guest_addr);
+        return err;
+    }
+
+    return 0;
+}
+
 int kvm_arch_get_registers(CPUState *cs)
 {
     int ret;
diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h
index bdb4f180eb..d34a16515f 100644
--- a/target/loongarch/kvm/kvm_loongarch.h
+++ b/target/loongarch/kvm/kvm_loongarch.h
@@ -12,6 +12,8 @@ 
 
 int  kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
 void kvm_arch_reset_vcpu(CPULoongArchState *env);
+int  kvm_loongarch_get_stealtime(LoongArchCPU *cpu);
+int  kvm_loongarch_put_stealtime(LoongArchCPU *cpu);
 
 #ifdef CONFIG_KVM
 /*
@@ -27,6 +29,16 @@  static inline bool kvm_feature_supported(CPUState *cs,
 {
     return false;
 }
+
+static inline int kvm_loongarch_get_stealtime(LoongArchCPU *cpu)
+{
+    return 0;
+}
+
+static inline int kvm_loongarch_put_stealtime(LoongArchCPU *cpu)
+{
+    return 0;
+}
 #endif
 
 #endif
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
index a371d5a2ab..344913703b 100644
--- a/target/loongarch/machine.c
+++ b/target/loongarch/machine.c
@@ -7,7 +7,9 @@ 
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "kvm/kvm_loongarch.h"
 #include "migration/cpu.h"
+#include "sysemu/kvm.h"
 #include "sysemu/tcg.h"
 #include "vec.h"
 
@@ -165,11 +167,29 @@  static const VMStateDescription vmstate_tlb = {
 };
 #endif
 
+static int cpu_post_load(void *opaque, int version_id)
+{
+    LoongArchCPU *cpu = opaque;
+
+    kvm_loongarch_put_stealtime(cpu);
+    return 0;
+}
+
+static int cpu_pre_save(void *opaque)
+{
+    LoongArchCPU *cpu = opaque;
+
+    kvm_loongarch_get_stealtime(cpu);
+    return 0;
+}
+
 /* LoongArch CPU state */
 const VMStateDescription vmstate_loongarch_cpu = {
     .name = "cpu",
-    .version_id = 2,
+    .version_id = 3,
     .minimum_version_id = 2,
+    .post_load = cpu_post_load,
+    .pre_save = cpu_pre_save,
     .fields = (const VMStateField[]) {
         VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
         VMSTATE_UINTTL(env.pc, LoongArchCPU),
@@ -232,6 +252,8 @@  const VMStateDescription vmstate_loongarch_cpu = {
         VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
 
         VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
+        /* PV steal time */
+        VMSTATE_UINT64(env.st.guest_addr, LoongArchCPU),
 
         VMSTATE_END_OF_LIST()
     },