From 8b69a1b340da95cacdff252927ca8aef9d43c33a Mon Sep 17 00:00:00 2001 From: Song Gao Date: Wed, 24 Apr 2024 16:06:33 +0800 Subject: [PATCH] target/loongarch/kvm: Add pv steal time support Signed-off-by: Song Gao --- 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