aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTianrui Zhao <zhaotianrui@loongson.cn>2024-01-05 15:58:01 +0800
committerSong Gao <gaosong@loongson.cn>2024-01-11 19:14:00 +0800
commitd11681c94f4b52d1e095e60ca101df80578437e5 (patch)
treef635a2f027a99586110c60d746f9ead6204046ac
parent41958c99e579f6d31545d93603da77133767e3f2 (diff)
downloadqemu-d11681c94f4b52d1e095e60ca101df80578437e5.zip
qemu-d11681c94f4b52d1e095e60ca101df80578437e5.tar.gz
qemu-d11681c94f4b52d1e095e60ca101df80578437e5.tar.bz2
target/loongarch: Implement kvm_arch_init_vcpu
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> Signed-off-by: xianglai li <lixianglai@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> Message-Id: <20240105075804.1228596-7-zhaotianrui@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn>
-rw-r--r--target/loongarch/cpu.h2
-rw-r--r--target/loongarch/kvm/kvm.c23
-rw-r--r--target/loongarch/trace-events2
3 files changed, 27 insertions, 0 deletions
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index a61c040..415c69e 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -381,6 +381,8 @@ struct ArchCPU {
/* 'compatible' string for this CPU for Linux device trees */
const char *dtb_compatible;
+ /* used by KVM_REG_LOONGARCH_COUNTER ioctl to access guest time counters */
+ uint64_t kvm_state_counter;
};
/**
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 29944b9..85e7aeb 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -617,8 +617,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_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
+ &cpu->kvm_state_counter);
+ if (ret < 0) {
+ trace_kvm_failed_put_counter(strerror(errno));
+ }
+ } else {
+ ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
+ &cpu->kvm_state_counter);
+ if (ret < 0) {
+ trace_kvm_failed_get_counter(strerror(errno));
+ }
+ }
+}
+
int kvm_arch_init_vcpu(CPUState *cs)
{
+ qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
return 0;
}
diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events
index 6827ab5..937c3c7 100644
--- a/target/loongarch/trace-events
+++ b/target/loongarch/trace-events
@@ -7,5 +7,7 @@ kvm_failed_get_fpu(const char *msg) "Failed to get fpu from KVM: %s"
kvm_failed_put_fpu(const char *msg) "Failed to put fpu into KVM: %s"
kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s"
kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s"
+kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s"
+kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s"
kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s"
kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"