@@ -350,6 +350,7 @@ struct ArchCPU {
/* 'compatible' string for this CPU for Linux device trees */
const char *dtb_compatible;
+ uint64_t counter_value;
};
#define TYPE_LOONGARCH_CPU "loongarch-cpu"
@@ -397,8 +397,31 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return ret;
}
+static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
+ RunState state)
+{
+ int ret;
+ CPUState *cs = opaque;
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+
+ if (running) {
+ ret = kvm_larch_putq(cs, KVM_REG_LOONGARCH_COUNTER,
+ &cpu->counter_value);
+ if (ret < 0) {
+ printf("%s: Failed to put counter_value (%d)\n", __func__, ret);
+ }
+ } else {
+ ret = kvm_larch_getq(cs, KVM_REG_LOONGARCH_COUNTER,
+ &cpu->counter_value);
+ if (ret < 0) {
+ printf("%s: Failed to get counter_value (%d)\n", __func__, ret);
+ }
+ }
+}
+
int kvm_arch_init_vcpu(CPUState *cs)
{
+ qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
return 0;
}
Implement kvm_arch_init_vcpu interface for loongarch, in this function, we register VM change state handler. And when VM state changes to running, the counter value should be put into kvm to keep consistent with kvm, and when state change to stop, counter value should be refreshed from kvm. Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> --- target/loongarch/cpu.h | 1 + target/loongarch/kvm.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+)