- target/loongarch: Fix qemu-system-loongarch64 assert - target/loongarch: Fix qemu-loongarch64 hang when executing 'll.d , , 0' - target/loongarch: Fix tlb huge page loading issue - target/loongarch/kvm: Add software breakpoint support - target/loongarch/kvm: sync kernel header files - hw/intc/loongarch_extioi: Add virt extension support - target/loongarch/kvm: Add pmu support - target/loongarch/kvm: Fix vm restore failed - target/loongarch/kvm: Add pv steal time support - target/loongarch/kvm: fpu save the vreg registers high Signed-off-by: Song Gao <gaosong@loongson.cn>
170 lines
4.9 KiB
Diff
170 lines
4.9 KiB
Diff
From 8b69a1b340da95cacdff252927ca8aef9d43c33a Mon Sep 17 00:00:00 2001
|
|
From: Song Gao <gaosong@loongson.cn>
|
|
Date: Wed, 24 Apr 2024 16:06:33 +0800
|
|
Subject: [PATCH] target/loongarch/kvm: Add pv steal time support
|
|
|
|
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
|
---
|
|
linux-headers/asm-loongarch/kvm.h | 2 ++
|
|
target/loongarch/cpu.h | 3 ++
|
|
target/loongarch/kvm/kvm.c | 50 ++++++++++++++++++++++++++++
|
|
target/loongarch/kvm/kvm_loongarch.h | 2 ++
|
|
target/loongarch/machine.c | 25 ++++++++++++++
|
|
5 files changed, 82 insertions(+)
|
|
|
|
diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h
|
|
index 4cec8c1601..81fec85f0a 100644
|
|
--- a/linux-headers/asm-loongarch/kvm.h
|
|
+++ b/linux-headers/asm-loongarch/kvm.h
|
|
@@ -84,6 +84,8 @@ struct kvm_fpu {
|
|
#define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG)
|
|
#define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)
|
|
#define KVM_LOONGARCH_VCPU_CPUCFG 0
|
|
+#define KVM_LOONGARCH_VCPU_PVTIME_CTRL 1
|
|
+#define KVM_LOONGARCH_VCPU_PVTIME_GPA 0
|
|
|
|
struct kvm_debug_exit_arch {
|
|
};
|
|
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
|
index 80cad24fa1..0ed24051af 100644
|
|
--- a/target/loongarch/cpu.h
|
|
+++ b/target/loongarch/cpu.h
|
|
@@ -365,6 +365,9 @@ typedef struct CPUArchState {
|
|
/* Store ipistate to access from this struct */
|
|
DeviceState *ipistate;
|
|
#endif
|
|
+ struct {
|
|
+ uint64_t guest_addr;
|
|
+ } st;
|
|
} CPULoongArchState;
|
|
|
|
/**
|
|
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
|
index 5dda631b2b..e1d521a1de 100644
|
|
--- a/target/loongarch/kvm/kvm.c
|
|
+++ b/target/loongarch/kvm/kvm.c
|
|
@@ -649,6 +649,56 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
|
|
return ret;
|
|
}
|
|
|
|
+int kvm_loongarch_put_pvtime(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 != 0) {
|
|
+ /* It's ok even though kvm has not such attr */
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_DEVICE_ATTR, attr);
|
|
+ if (err != 0) {
|
|
+ error_report("PVTIME IPA: KVM_SET_DEVICE_ATTR: %s", strerror(-err));
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int kvm_loongarch_get_pvtime(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 != 0) {
|
|
+ /* It's ok even though kvm has not such attr */
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_DEVICE_ATTR, attr);
|
|
+ if (err != 0) {
|
|
+ error_report("PVTIME IPA: KVM_GET_DEVICE_ATTR: %s", strerror(-err));
|
|
+ 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 d945b6bb82..551878a725 100644
|
|
--- a/target/loongarch/kvm/kvm_loongarch.h
|
|
+++ b/target/loongarch/kvm/kvm_loongarch.h
|
|
@@ -12,5 +12,7 @@
|
|
|
|
int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
|
|
void kvm_arch_reset_vcpu(CPULoongArchState *env);
|
|
+int kvm_loongarch_put_pvtime(LoongArchCPU *cpu);
|
|
+int kvm_loongarch_get_pvtime(LoongArchCPU *cpu);
|
|
|
|
#endif
|
|
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
|
|
index 4443caed2d..ec5abe56db 100644
|
|
--- a/target/loongarch/machine.c
|
|
+++ b/target/loongarch/machine.c
|
|
@@ -9,6 +9,8 @@
|
|
#include "cpu.h"
|
|
#include "migration/cpu.h"
|
|
#include "vec.h"
|
|
+#include "kvm/kvm_loongarch.h"
|
|
+#include "sysemu/kvm.h"
|
|
|
|
static const VMStateDescription vmstate_fpu_reg = {
|
|
.name = "fpu_reg",
|
|
@@ -122,15 +124,38 @@ const VMStateDescription vmstate_tlb = {
|
|
}
|
|
};
|
|
|
|
+static int cpu_post_load(void *opaque, int version_id)
|
|
+{
|
|
+#ifdef CONFIG_KVM
|
|
+ LoongArchCPU *cpu = opaque;
|
|
+ kvm_loongarch_put_pvtime(cpu);
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cpu_pre_save(void *opaque)
|
|
+{
|
|
+#ifdef CONFIG_KVM
|
|
+ LoongArchCPU *cpu = opaque;
|
|
+ kvm_loongarch_get_pvtime(cpu);
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* LoongArch CPU state */
|
|
const VMStateDescription vmstate_loongarch_cpu = {
|
|
.name = "cpu",
|
|
.version_id = 1,
|
|
.minimum_version_id = 1,
|
|
+ .post_load = cpu_post_load,
|
|
+ .pre_save = cpu_pre_save,
|
|
.fields = (VMStateField[]) {
|
|
VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
|
|
VMSTATE_UINTTL(env.pc, LoongArchCPU),
|
|
|
|
+ /* PV time */
|
|
+ VMSTATE_UINT64(env.st.guest_addr, LoongArchCPU),
|
|
+
|
|
/* Remaining CSRs */
|
|
VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
|
|
VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU),
|
|
--
|
|
2.33.0
|
|
|